OSDN Git Service

Disable app pinning when emergency call button pressed
[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.internal.util.ProgressReporter;
45 import com.android.server.AppOpsService;
46 import com.android.server.AttributeCache;
47 import com.android.server.DeviceIdleController;
48 import com.android.server.IntentResolver;
49 import com.android.server.LocalServices;
50 import com.android.server.LockGuard;
51 import com.android.server.ServiceThread;
52 import com.android.server.SystemService;
53 import com.android.server.SystemServiceManager;
54 import com.android.server.Watchdog;
55 import com.android.server.am.ActivityStack.ActivityState;
56 import com.android.server.firewall.IntentFirewall;
57 import com.android.server.pm.Installer;
58 import com.android.server.statusbar.StatusBarManagerInternal;
59 import com.android.server.vr.VrManagerInternal;
60 import com.android.server.wm.WindowManagerService;
61
62 import org.xmlpull.v1.XmlPullParser;
63 import org.xmlpull.v1.XmlPullParserException;
64 import org.xmlpull.v1.XmlSerializer;
65
66 import android.Manifest;
67 import android.annotation.UserIdInt;
68 import android.app.Activity;
69 import android.app.ActivityManager;
70 import android.app.ActivityManager.RunningTaskInfo;
71 import android.app.ActivityManager.StackId;
72 import android.app.ActivityManager.StackInfo;
73 import android.app.ActivityManager.TaskThumbnailInfo;
74 import android.app.ActivityManagerInternal;
75 import android.app.ActivityManagerInternal.SleepToken;
76 import android.app.ActivityManagerNative;
77 import android.app.ActivityOptions;
78 import android.app.ActivityThread;
79 import android.app.AlertDialog;
80 import android.app.AppGlobals;
81 import android.app.AppOpsManager;
82 import android.app.ApplicationErrorReport;
83 import android.app.ApplicationThreadNative;
84 import android.app.BroadcastOptions;
85 import android.app.Dialog;
86 import android.app.IActivityContainer;
87 import android.app.IActivityContainerCallback;
88 import android.app.IActivityController;
89 import android.app.IAppTask;
90 import android.app.IApplicationThread;
91 import android.app.IInstrumentationWatcher;
92 import android.app.INotificationManager;
93 import android.app.IProcessObserver;
94 import android.app.IServiceConnection;
95 import android.app.IStopUserCallback;
96 import android.app.ITaskStackListener;
97 import android.app.IUiAutomationConnection;
98 import android.app.IUidObserver;
99 import android.app.IUserSwitchObserver;
100 import android.app.Instrumentation;
101 import android.app.KeyguardManager;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.admin.DevicePolicyManagerInternal;
108 import android.app.assist.AssistContent;
109 import android.app.assist.AssistStructure;
110 import android.app.backup.IBackupManager;
111 import android.app.usage.UsageEvents;
112 import android.app.usage.UsageStatsManagerInternal;
113 import android.appwidget.AppWidgetManager;
114 import android.content.ActivityNotFoundException;
115 import android.content.BroadcastReceiver;
116 import android.content.ClipData;
117 import android.content.ComponentCallbacks2;
118 import android.content.ComponentName;
119 import android.content.ContentProvider;
120 import android.content.ContentResolver;
121 import android.content.Context;
122 import android.content.DialogInterface;
123 import android.content.IContentProvider;
124 import android.content.IIntentReceiver;
125 import android.content.IIntentSender;
126 import android.content.Intent;
127 import android.content.IntentFilter;
128 import android.content.IntentSender;
129 import android.content.pm.ActivityInfo;
130 import android.content.pm.ApplicationInfo;
131 import android.content.pm.ConfigurationInfo;
132 import android.content.pm.IPackageDataObserver;
133 import android.content.pm.IPackageManager;
134 import android.content.pm.InstrumentationInfo;
135 import android.content.pm.PackageInfo;
136 import android.content.pm.PackageManager;
137 import android.content.pm.PackageManager.NameNotFoundException;
138 import android.content.pm.PackageManagerInternal;
139 import android.content.pm.ParceledListSlice;
140 import android.content.pm.PathPermission;
141 import android.content.pm.PermissionInfo;
142 import android.content.pm.ProviderInfo;
143 import android.content.pm.ResolveInfo;
144 import android.content.pm.ServiceInfo;
145 import android.content.pm.ShortcutServiceInternal;
146 import android.content.pm.UserInfo;
147 import android.content.res.CompatibilityInfo;
148 import android.content.res.Configuration;
149 import android.content.res.Resources;
150 import android.database.ContentObserver;
151 import android.graphics.Bitmap;
152 import android.graphics.Point;
153 import android.graphics.Rect;
154 import android.location.LocationManager;
155 import android.net.Proxy;
156 import android.net.ProxyInfo;
157 import android.net.Uri;
158 import android.os.BatteryStats;
159 import android.os.Binder;
160 import android.os.Build;
161 import android.os.Bundle;
162 import android.os.Debug;
163 import android.os.DropBoxManager;
164 import android.os.Environment;
165 import android.os.FactoryTest;
166 import android.os.FileObserver;
167 import android.os.FileUtils;
168 import android.os.Handler;
169 import android.os.IBinder;
170 import android.os.IPermissionController;
171 import android.os.IProcessInfoService;
172 import android.os.IProgressListener;
173 import android.os.LocaleList;
174 import android.os.Looper;
175 import android.os.Message;
176 import android.os.Parcel;
177 import android.os.ParcelFileDescriptor;
178 import android.os.PersistableBundle;
179 import android.os.PowerManager;
180 import android.os.PowerManagerInternal;
181 import android.os.Process;
182 import android.os.RemoteCallbackList;
183 import android.os.RemoteException;
184 import android.os.ResultReceiver;
185 import android.os.ServiceManager;
186 import android.os.StrictMode;
187 import android.os.SystemClock;
188 import android.os.SystemProperties;
189 import android.os.Trace;
190 import android.os.TransactionTooLargeException;
191 import android.os.UpdateLock;
192 import android.os.UserHandle;
193 import android.os.UserManager;
194 import android.os.WorkSource;
195 import android.os.storage.IMountService;
196 import android.os.storage.MountServiceInternal;
197 import android.os.storage.StorageManager;
198 import android.provider.Settings;
199 import android.service.voice.IVoiceInteractionSession;
200 import android.service.voice.VoiceInteractionManagerInternal;
201 import android.service.voice.VoiceInteractionSession;
202 import android.telecom.TelecomManager;
203 import android.text.format.DateUtils;
204 import android.text.format.Time;
205 import android.text.style.SuggestionSpan;
206 import android.util.ArrayMap;
207 import android.util.ArraySet;
208 import android.util.AtomicFile;
209 import android.util.DebugUtils;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
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.FIRST_STATIC_STACK_ID;
263 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
268 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
270 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
271 import static android.content.pm.PackageManager.GET_PROVIDERS;
272 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
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.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
279 import static android.provider.Settings.Global.DEBUG_APP;
280 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
281 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
282 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
283 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
284 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
285 import static android.provider.Settings.System.FONT_SCALE;
286 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
287 import static com.android.internal.util.XmlUtils.readIntAttribute;
288 import static com.android.internal.util.XmlUtils.readLongAttribute;
289 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
290 import static com.android.internal.util.XmlUtils.writeIntAttribute;
291 import static com.android.internal.util.XmlUtils.writeLongAttribute;
292 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
324 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
325 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
348 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
349 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
350 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
351 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
352 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
353 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
354 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
355 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
356 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
357 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
358 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
359 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
360 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
361 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
362 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
363 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
364 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
365 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
366 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
367 import static org.xmlpull.v1.XmlPullParser.START_TAG;
368
369 public final class ActivityManagerService extends ActivityManagerNative
370         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
371
372     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
373     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
374     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
375     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
376     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
377     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
378     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
379     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
380     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
381     private static final String TAG_LRU = TAG + POSTFIX_LRU;
382     private static final String TAG_MU = TAG + POSTFIX_MU;
383     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
384     private static final String TAG_POWER = TAG + POSTFIX_POWER;
385     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
386     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
387     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
388     private static final String TAG_PSS = TAG + POSTFIX_PSS;
389     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
390     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
391     private static final String TAG_STACK = TAG + POSTFIX_STACK;
392     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
393     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
394     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
395     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
396     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
397
398     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
399     // here so that while the job scheduler can depend on AMS, the other way around
400     // need not be the case.
401     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
402
403     /** Control over CPU and battery monitoring */
404     // write battery stats every 30 minutes.
405     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
406     static final boolean MONITOR_CPU_USAGE = true;
407     // don't sample cpu less than every 5 seconds.
408     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
409     // wait possibly forever for next cpu sample.
410     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
411     static final boolean MONITOR_THREAD_CPU_USAGE = false;
412
413     // The flags that are set for all calls we make to the package manager.
414     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
415
416     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
417
418     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
419
420     // Amount of time after a call to stopAppSwitches() during which we will
421     // prevent further untrusted switches from happening.
422     static final long APP_SWITCH_DELAY_TIME = 5*1000;
423
424     // How long we wait for a launched process to attach to the activity manager
425     // before we decide it's never going to come up for real.
426     static final int PROC_START_TIMEOUT = 10*1000;
427     // How long we wait for an attached process to publish its content providers
428     // before we decide it must be hung.
429     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
430
431     // How long we will retain processes hosting content providers in the "last activity"
432     // state before allowing them to drop down to the regular cached LRU list.  This is
433     // to avoid thrashing of provider processes under low memory situations.
434     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
435
436     // How long we wait for a launched process to attach to the activity manager
437     // before we decide it's never going to come up for real, when the process was
438     // started with a wrapper for instrumentation (such as Valgrind) because it
439     // could take much longer than usual.
440     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
441
442     // How long to wait after going idle before forcing apps to GC.
443     static final int GC_TIMEOUT = 5*1000;
444
445     // The minimum amount of time between successive GC requests for a process.
446     static final int GC_MIN_INTERVAL = 60*1000;
447
448     // The minimum amount of time between successive PSS requests for a process.
449     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
450
451     // The minimum amount of time between successive PSS requests for a process
452     // when the request is due to the memory state being lowered.
453     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
454
455     // The rate at which we check for apps using excessive power -- 15 mins.
456     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
457
458     // The minimum sample duration we will allow before deciding we have
459     // enough data on wake locks to start killing things.
460     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462     // The minimum sample duration we will allow before deciding we have
463     // enough data on CPU usage to start killing things.
464     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466     // How long we allow a receiver to run before giving up on it.
467     static final int BROADCAST_FG_TIMEOUT = 10*1000;
468     static final int BROADCAST_BG_TIMEOUT = 60*1000;
469
470     // How long we wait until we timeout on key dispatching.
471     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
472
473     // How long we wait until we timeout on key dispatching during instrumentation.
474     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
475
476     // This is the amount of time an app needs to be running a foreground service before
477     // we will consider it to be doing interaction for usage stats.
478     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
479
480     // Maximum amount of time we will allow to elapse before re-reporting usage stats
481     // interaction with foreground processes.
482     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
483
484     // This is the amount of time we allow an app to settle after it goes into the background,
485     // before we start restricting what it can do.
486     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
487
488     // How long to wait in getAssistContextExtras for the activity and foreground services
489     // to respond with the result.
490     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
491
492     // How long top wait when going through the modern assist (which doesn't need to block
493     // on getting this result before starting to launch its UI).
494     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
495
496     // Maximum number of persisted Uri grants a package is allowed
497     static final int MAX_PERSISTED_URI_GRANTS = 128;
498
499     static final int MY_PID = Process.myPid();
500
501     static final String[] EMPTY_STRING_ARRAY = new String[0];
502
503     // How many bytes to write into the dropbox log before truncating
504     static final int DROPBOX_MAX_SIZE = 256 * 1024;
505
506     // Access modes for handleIncomingUser.
507     static final int ALLOW_NON_FULL = 0;
508     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
509     static final int ALLOW_FULL_ONLY = 2;
510
511     // Delay in notifying task stack change listeners (in millis)
512     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
513
514     // Necessary ApplicationInfo flags to mark an app as persistent
515     private static final int PERSISTENT_MASK =
516             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
517
518     // Intent sent when remote bugreport collection has been completed
519     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
520             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
521
522     // Delay to disable app launch boost
523     static final int APP_BOOST_MESSAGE_DELAY = 3000;
524     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
525     static final int APP_BOOST_TIMEOUT = 2500;
526
527     // Used to indicate that a task is removed it should also be removed from recents.
528     private static final boolean REMOVE_FROM_RECENTS = true;
529     // Used to indicate that an app transition should be animated.
530     static final boolean ANIMATE = true;
531
532     // Determines whether to take full screen screenshots
533     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
534     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
535
536     private static native int nativeMigrateToBoost();
537     private static native int nativeMigrateFromBoost();
538     private boolean mIsBoosted = false;
539     private long mBoostStartTime = 0;
540
541     /** All system services */
542     SystemServiceManager mSystemServiceManager;
543
544     private Installer mInstaller;
545
546     /** Run all ActivityStacks through this */
547     final ActivityStackSupervisor mStackSupervisor;
548
549     final ActivityStarter mActivityStarter;
550
551     /** Task stack change listeners. */
552     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
553             new RemoteCallbackList<ITaskStackListener>();
554
555     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
556
557     public IntentFirewall mIntentFirewall;
558
559     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
560     // default actuion automatically.  Important for devices without direct input
561     // devices.
562     private boolean mShowDialogs = true;
563     private boolean mInVrMode = false;
564
565     BroadcastQueue mFgBroadcastQueue;
566     BroadcastQueue mBgBroadcastQueue;
567     // Convenient for easy iteration over the queues. Foreground is first
568     // so that dispatch of foreground broadcasts gets precedence.
569     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
570
571     BroadcastQueue broadcastQueueForIntent(Intent intent) {
572         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
573         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
574                 "Broadcast intent " + intent + " on "
575                 + (isFg ? "foreground" : "background") + " queue");
576         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
577     }
578
579     /**
580      * Activity we have told the window manager to have key focus.
581      */
582     ActivityRecord mFocusedActivity = null;
583
584     /**
585      * User id of the last activity mFocusedActivity was set to.
586      */
587     private int mLastFocusedUserId;
588
589     /**
590      * If non-null, we are tracking the time the user spends in the currently focused app.
591      */
592     private AppTimeTracker mCurAppTimeTracker;
593
594     /**
595      * List of intents that were used to start the most recent tasks.
596      */
597     final RecentTasks mRecentTasks;
598
599     /**
600      * For addAppTask: cached of the last activity component that was added.
601      */
602     ComponentName mLastAddedTaskComponent;
603
604     /**
605      * For addAppTask: cached of the last activity uid that was added.
606      */
607     int mLastAddedTaskUid;
608
609     /**
610      * For addAppTask: cached of the last ActivityInfo that was added.
611      */
612     ActivityInfo mLastAddedTaskActivity;
613
614     /**
615      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
616      */
617     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
618
619     /**
620      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
621      */
622     String mDeviceOwnerName;
623
624     final UserController mUserController;
625
626     final AppErrors mAppErrors;
627
628     boolean mDoingSetFocusedActivity;
629
630     public boolean canShowErrorDialogs() {
631         return mShowDialogs && !mSleeping && !mShuttingDown;
632     }
633
634     // it's a semaphore; boost when 0->1, reset when 1->0
635     static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
636         @Override protected Integer initialValue() {
637             return 0;
638         }
639     };
640
641     static void boostPriorityForLockedSection() {
642         if (sIsBoosted.get() == 0) {
643             // boost to prio 118 while holding a global lock
644             Process.setThreadPriority(Process.myTid(), -2);
645             //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
646         }
647         int cur = sIsBoosted.get();
648         sIsBoosted.set(cur + 1);
649     }
650
651     static void resetPriorityAfterLockedSection() {
652         sIsBoosted.set(sIsBoosted.get() - 1);
653         if (sIsBoosted.get() == 0) {
654             //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
655             Process.setThreadPriority(Process.myTid(), 0);
656         }
657     }
658     public class PendingAssistExtras extends Binder implements Runnable {
659         public final ActivityRecord activity;
660         public final Bundle extras;
661         public final Intent intent;
662         public final String hint;
663         public final IResultReceiver receiver;
664         public final int userHandle;
665         public boolean haveResult = false;
666         public Bundle result = null;
667         public AssistStructure structure = null;
668         public AssistContent content = null;
669         public Bundle receiverExtras;
670
671         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
672                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
673             activity = _activity;
674             extras = _extras;
675             intent = _intent;
676             hint = _hint;
677             receiver = _receiver;
678             receiverExtras = _receiverExtras;
679             userHandle = _userHandle;
680         }
681         @Override
682         public void run() {
683             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
684             synchronized (this) {
685                 haveResult = true;
686                 notifyAll();
687             }
688             pendingAssistExtrasTimedOut(this);
689         }
690     }
691
692     final ArrayList<PendingAssistExtras> mPendingAssistExtras
693             = new ArrayList<PendingAssistExtras>();
694
695     /**
696      * Process management.
697      */
698     final ProcessList mProcessList = new ProcessList();
699
700     /**
701      * All of the applications we currently have running organized by name.
702      * The keys are strings of the application package name (as
703      * returned by the package manager), and the keys are ApplicationRecord
704      * objects.
705      */
706     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
707
708     /**
709      * Tracking long-term execution of processes to look for abuse and other
710      * bad app behavior.
711      */
712     final ProcessStatsService mProcessStats;
713
714     /**
715      * The currently running isolated processes.
716      */
717     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
718
719     /**
720      * Counter for assigning isolated process uids, to avoid frequently reusing the
721      * same ones.
722      */
723     int mNextIsolatedProcessUid = 0;
724
725     /**
726      * The currently running heavy-weight process, if any.
727      */
728     ProcessRecord mHeavyWeightProcess = null;
729
730     /**
731      * All of the processes we currently have running organized by pid.
732      * The keys are the pid running the application.
733      *
734      * <p>NOTE: This object is protected by its own lock, NOT the global
735      * activity manager lock!
736      */
737     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
738
739     /**
740      * All of the processes that have been forced to be foreground.  The key
741      * is the pid of the caller who requested it (we hold a death
742      * link on it).
743      */
744     abstract class ForegroundToken implements IBinder.DeathRecipient {
745         int pid;
746         IBinder token;
747     }
748     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
749
750     /**
751      * List of records for processes that someone had tried to start before the
752      * system was ready.  We don't start them at that point, but ensure they
753      * are started by the time booting is complete.
754      */
755     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
756
757     /**
758      * List of persistent applications that are in the process
759      * of being started.
760      */
761     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
762
763     /**
764      * Processes that are being forcibly torn down.
765      */
766     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
767
768     /**
769      * List of running applications, sorted by recent usage.
770      * The first entry in the list is the least recently used.
771      */
772     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
773
774     /**
775      * Where in mLruProcesses that the processes hosting activities start.
776      */
777     int mLruProcessActivityStart = 0;
778
779     /**
780      * Where in mLruProcesses that the processes hosting services start.
781      * This is after (lower index) than mLruProcessesActivityStart.
782      */
783     int mLruProcessServiceStart = 0;
784
785     /**
786      * List of processes that should gc as soon as things are idle.
787      */
788     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
789
790     /**
791      * Processes we want to collect PSS data from.
792      */
793     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
794
795     private boolean mBinderTransactionTrackingEnabled = false;
796
797     /**
798      * Last time we requested PSS data of all processes.
799      */
800     long mLastFullPssTime = SystemClock.uptimeMillis();
801
802     /**
803      * If set, the next time we collect PSS data we should do a full collection
804      * with data from native processes and the kernel.
805      */
806     boolean mFullPssPending = false;
807
808     /**
809      * This is the process holding what we currently consider to be
810      * the "home" activity.
811      */
812     ProcessRecord mHomeProcess;
813
814     /**
815      * This is the process holding the activity the user last visited that
816      * is in a different process from the one they are currently in.
817      */
818     ProcessRecord mPreviousProcess;
819
820     /**
821      * The time at which the previous process was last visible.
822      */
823     long mPreviousProcessVisibleTime;
824
825     /**
826      * Track all uids that have actively running processes.
827      */
828     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
829
830     /**
831      * This is for verifying the UID report flow.
832      */
833     static final boolean VALIDATE_UID_STATES = true;
834     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
835
836     /**
837      * Packages that the user has asked to have run in screen size
838      * compatibility mode instead of filling the screen.
839      */
840     final CompatModePackages mCompatModePackages;
841
842     /**
843      * Set of IntentSenderRecord objects that are currently active.
844      */
845     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
846             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
847
848     /**
849      * Fingerprints (hashCode()) of stack traces that we've
850      * already logged DropBox entries for.  Guarded by itself.  If
851      * something (rogue user app) forces this over
852      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
853      */
854     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
855     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
856
857     /**
858      * Strict Mode background batched logging state.
859      *
860      * The string buffer is guarded by itself, and its lock is also
861      * used to determine if another batched write is already
862      * in-flight.
863      */
864     private final StringBuilder mStrictModeBuffer = new StringBuilder();
865
866     /**
867      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
868      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
869      */
870     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
871
872     /**
873      * Resolver for broadcast intents to registered receivers.
874      * Holds BroadcastFilter (subclass of IntentFilter).
875      */
876     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
877             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
878         @Override
879         protected boolean allowFilterResult(
880                 BroadcastFilter filter, List<BroadcastFilter> dest) {
881             IBinder target = filter.receiverList.receiver.asBinder();
882             for (int i = dest.size() - 1; i >= 0; i--) {
883                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
884                     return false;
885                 }
886             }
887             return true;
888         }
889
890         @Override
891         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
892             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
893                     || userId == filter.owningUserId) {
894                 return super.newResult(filter, match, userId);
895             }
896             return null;
897         }
898
899         @Override
900         protected BroadcastFilter[] newArray(int size) {
901             return new BroadcastFilter[size];
902         }
903
904         @Override
905         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
906             return packageName.equals(filter.packageName);
907         }
908     };
909
910     /**
911      * State of all active sticky broadcasts per user.  Keys are the action of the
912      * sticky Intent, values are an ArrayList of all broadcasted intents with
913      * that action (which should usually be one).  The SparseArray is keyed
914      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
915      * for stickies that are sent to all users.
916      */
917     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
918             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
919
920     final ActiveServices mServices;
921
922     final static class Association {
923         final int mSourceUid;
924         final String mSourceProcess;
925         final int mTargetUid;
926         final ComponentName mTargetComponent;
927         final String mTargetProcess;
928
929         int mCount;
930         long mTime;
931
932         int mNesting;
933         long mStartTime;
934
935         // states of the source process when the bind occurred.
936         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
937         long mLastStateUptime;
938         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
939                 - ActivityManager.MIN_PROCESS_STATE+1];
940
941         Association(int sourceUid, String sourceProcess, int targetUid,
942                 ComponentName targetComponent, String targetProcess) {
943             mSourceUid = sourceUid;
944             mSourceProcess = sourceProcess;
945             mTargetUid = targetUid;
946             mTargetComponent = targetComponent;
947             mTargetProcess = targetProcess;
948         }
949     }
950
951     /**
952      * When service association tracking is enabled, this is all of the associations we
953      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
954      * -> association data.
955      */
956     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
957             mAssociations = new SparseArray<>();
958     boolean mTrackingAssociations;
959
960     /**
961      * Backup/restore process management
962      */
963     String mBackupAppName = null;
964     BackupRecord mBackupTarget = null;
965
966     final ProviderMap mProviderMap;
967
968     /**
969      * List of content providers who have clients waiting for them.  The
970      * application is currently being launched and the provider will be
971      * removed from this list once it is published.
972      */
973     final ArrayList<ContentProviderRecord> mLaunchingProviders
974             = new ArrayList<ContentProviderRecord>();
975
976     /**
977      * File storing persisted {@link #mGrantedUriPermissions}.
978      */
979     private final AtomicFile mGrantFile;
980
981     /** XML constants used in {@link #mGrantFile} */
982     private static final String TAG_URI_GRANTS = "uri-grants";
983     private static final String TAG_URI_GRANT = "uri-grant";
984     private static final String ATTR_USER_HANDLE = "userHandle";
985     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
986     private static final String ATTR_TARGET_USER_ID = "targetUserId";
987     private static final String ATTR_SOURCE_PKG = "sourcePkg";
988     private static final String ATTR_TARGET_PKG = "targetPkg";
989     private static final String ATTR_URI = "uri";
990     private static final String ATTR_MODE_FLAGS = "modeFlags";
991     private static final String ATTR_CREATED_TIME = "createdTime";
992     private static final String ATTR_PREFIX = "prefix";
993
994     /**
995      * Global set of specific {@link Uri} permissions that have been granted.
996      * This optimized lookup structure maps from {@link UriPermission#targetUid}
997      * to {@link UriPermission#uri} to {@link UriPermission}.
998      */
999     @GuardedBy("this")
1000     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1001             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1002
1003     public static class GrantUri {
1004         public final int sourceUserId;
1005         public final Uri uri;
1006         public boolean prefix;
1007
1008         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1009             this.sourceUserId = sourceUserId;
1010             this.uri = uri;
1011             this.prefix = prefix;
1012         }
1013
1014         @Override
1015         public int hashCode() {
1016             int hashCode = 1;
1017             hashCode = 31 * hashCode + sourceUserId;
1018             hashCode = 31 * hashCode + uri.hashCode();
1019             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1020             return hashCode;
1021         }
1022
1023         @Override
1024         public boolean equals(Object o) {
1025             if (o instanceof GrantUri) {
1026                 GrantUri other = (GrantUri) o;
1027                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1028                         && prefix == other.prefix;
1029             }
1030             return false;
1031         }
1032
1033         @Override
1034         public String toString() {
1035             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1036             if (prefix) result += " [prefix]";
1037             return result;
1038         }
1039
1040         public String toSafeString() {
1041             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1042             if (prefix) result += " [prefix]";
1043             return result;
1044         }
1045
1046         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1047             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1048                     ContentProvider.getUriWithoutUserId(uri), false);
1049         }
1050     }
1051
1052     CoreSettingsObserver mCoreSettingsObserver;
1053
1054     FontScaleSettingObserver mFontScaleSettingObserver;
1055
1056     private final class FontScaleSettingObserver extends ContentObserver {
1057         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1058
1059         public FontScaleSettingObserver() {
1060             super(mHandler);
1061             ContentResolver resolver = mContext.getContentResolver();
1062             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1063         }
1064
1065         @Override
1066         public void onChange(boolean selfChange, Uri uri) {
1067             if (mFontScaleUri.equals(uri)) {
1068                 updateFontScaleIfNeeded();
1069             }
1070         }
1071     }
1072
1073     /**
1074      * Thread-local storage used to carry caller permissions over through
1075      * indirect content-provider access.
1076      */
1077     private class Identity {
1078         public final IBinder token;
1079         public final int pid;
1080         public final int uid;
1081
1082         Identity(IBinder _token, int _pid, int _uid) {
1083             token = _token;
1084             pid = _pid;
1085             uid = _uid;
1086         }
1087     }
1088
1089     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1090
1091     /**
1092      * All information we have collected about the runtime performance of
1093      * any user id that can impact battery performance.
1094      */
1095     final BatteryStatsService mBatteryStatsService;
1096
1097     /**
1098      * Information about component usage
1099      */
1100     UsageStatsManagerInternal mUsageStatsService;
1101
1102     /**
1103      * Access to DeviceIdleController service.
1104      */
1105     DeviceIdleController.LocalService mLocalDeviceIdleController;
1106
1107     /**
1108      * Information about and control over application operations
1109      */
1110     final AppOpsService mAppOpsService;
1111
1112     /**
1113      * Current configuration information.  HistoryRecord objects are given
1114      * a reference to this object to indicate which configuration they are
1115      * currently running in, so this object must be kept immutable.
1116      */
1117     Configuration mConfiguration = new Configuration();
1118
1119     /**
1120      * Current sequencing integer of the configuration, for skipping old
1121      * configurations.
1122      */
1123     int mConfigurationSeq = 0;
1124
1125     boolean mSuppressResizeConfigChanges = false;
1126
1127     /**
1128      * Hardware-reported OpenGLES version.
1129      */
1130     final int GL_ES_VERSION;
1131
1132     /**
1133      * List of initialization arguments to pass to all processes when binding applications to them.
1134      * For example, references to the commonly used services.
1135      */
1136     HashMap<String, IBinder> mAppBindArgs;
1137
1138     /**
1139      * Temporary to avoid allocations.  Protected by main lock.
1140      */
1141     final StringBuilder mStringBuilder = new StringBuilder(256);
1142
1143     /**
1144      * Used to control how we initialize the service.
1145      */
1146     ComponentName mTopComponent;
1147     String mTopAction = Intent.ACTION_MAIN;
1148     String mTopData;
1149
1150     volatile boolean mProcessesReady = false;
1151     volatile boolean mSystemReady = false;
1152     volatile boolean mOnBattery = false;
1153     volatile int mFactoryTest;
1154
1155     @GuardedBy("this") boolean mBooting = false;
1156     @GuardedBy("this") boolean mCallFinishBooting = false;
1157     @GuardedBy("this") boolean mBootAnimationComplete = false;
1158     @GuardedBy("this") boolean mLaunchWarningShown = false;
1159     @GuardedBy("this") boolean mCheckedForSetup = false;
1160
1161     Context mContext;
1162
1163     /**
1164      * The time at which we will allow normal application switches again,
1165      * after a call to {@link #stopAppSwitches()}.
1166      */
1167     long mAppSwitchesAllowedTime;
1168
1169     /**
1170      * This is set to true after the first switch after mAppSwitchesAllowedTime
1171      * is set; any switches after that will clear the time.
1172      */
1173     boolean mDidAppSwitch;
1174
1175     /**
1176      * Last time (in realtime) at which we checked for power usage.
1177      */
1178     long mLastPowerCheckRealtime;
1179
1180     /**
1181      * Last time (in uptime) at which we checked for power usage.
1182      */
1183     long mLastPowerCheckUptime;
1184
1185     /**
1186      * Set while we are wanting to sleep, to prevent any
1187      * activities from being started/resumed.
1188      */
1189     private boolean mSleeping = false;
1190
1191     /**
1192      * The process state used for processes that are running the top activities.
1193      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1194      */
1195     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1196
1197     /**
1198      * Set while we are running a voice interaction.  This overrides
1199      * sleeping while it is active.
1200      */
1201     private IVoiceInteractionSession mRunningVoice;
1202
1203     /**
1204      * For some direct access we need to power manager.
1205      */
1206     PowerManagerInternal mLocalPowerManager;
1207
1208     /**
1209      * We want to hold a wake lock while running a voice interaction session, since
1210      * this may happen with the screen off and we need to keep the CPU running to
1211      * be able to continue to interact with the user.
1212      */
1213     PowerManager.WakeLock mVoiceWakeLock;
1214
1215     /**
1216      * State of external calls telling us if the device is awake or asleep.
1217      */
1218     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1219
1220     /**
1221      * A list of tokens that cause the top activity to be put to sleep.
1222      * They are used by components that may hide and block interaction with underlying
1223      * activities.
1224      */
1225     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1226
1227     static final int LOCK_SCREEN_HIDDEN = 0;
1228     static final int LOCK_SCREEN_LEAVING = 1;
1229     static final int LOCK_SCREEN_SHOWN = 2;
1230     /**
1231      * State of external call telling us if the lock screen is shown.
1232      */
1233     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1234
1235     /**
1236      * Set if we are shutting down the system, similar to sleeping.
1237      */
1238     boolean mShuttingDown = false;
1239
1240     /**
1241      * Current sequence id for oom_adj computation traversal.
1242      */
1243     int mAdjSeq = 0;
1244
1245     /**
1246      * Current sequence id for process LRU updating.
1247      */
1248     int mLruSeq = 0;
1249
1250     /**
1251      * Keep track of the non-cached/empty process we last found, to help
1252      * determine how to distribute cached/empty processes next time.
1253      */
1254     int mNumNonCachedProcs = 0;
1255
1256     /**
1257      * Keep track of the number of cached hidden procs, to balance oom adj
1258      * distribution between those and empty procs.
1259      */
1260     int mNumCachedHiddenProcs = 0;
1261
1262     /**
1263      * Keep track of the number of service processes we last found, to
1264      * determine on the next iteration which should be B services.
1265      */
1266     int mNumServiceProcs = 0;
1267     int mNewNumAServiceProcs = 0;
1268     int mNewNumServiceProcs = 0;
1269
1270     /**
1271      * Allow the current computed overall memory level of the system to go down?
1272      * This is set to false when we are killing processes for reasons other than
1273      * memory management, so that the now smaller process list will not be taken as
1274      * an indication that memory is tighter.
1275      */
1276     boolean mAllowLowerMemLevel = false;
1277
1278     /**
1279      * The last computed memory level, for holding when we are in a state that
1280      * processes are going away for other reasons.
1281      */
1282     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1283
1284     /**
1285      * The last total number of process we have, to determine if changes actually look
1286      * like a shrinking number of process due to lower RAM.
1287      */
1288     int mLastNumProcesses;
1289
1290     /**
1291      * The uptime of the last time we performed idle maintenance.
1292      */
1293     long mLastIdleTime = SystemClock.uptimeMillis();
1294
1295     /**
1296      * Total time spent with RAM that has been added in the past since the last idle time.
1297      */
1298     long mLowRamTimeSinceLastIdle = 0;
1299
1300     /**
1301      * If RAM is currently low, when that horrible situation started.
1302      */
1303     long mLowRamStartTime = 0;
1304
1305     /**
1306      * For reporting to battery stats the current top application.
1307      */
1308     private String mCurResumedPackage = null;
1309     private int mCurResumedUid = -1;
1310
1311     /**
1312      * For reporting to battery stats the apps currently running foreground
1313      * service.  The ProcessMap is package/uid tuples; each of these contain
1314      * an array of the currently foreground processes.
1315      */
1316     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1317             = new ProcessMap<ArrayList<ProcessRecord>>();
1318
1319     /**
1320      * This is set if we had to do a delayed dexopt of an app before launching
1321      * it, to increase the ANR timeouts in that case.
1322      */
1323     boolean mDidDexOpt;
1324
1325     /**
1326      * Set if the systemServer made a call to enterSafeMode.
1327      */
1328     boolean mSafeMode;
1329
1330     /**
1331      * If true, we are running under a test environment so will sample PSS from processes
1332      * much more rapidly to try to collect better data when the tests are rapidly
1333      * running through apps.
1334      */
1335     boolean mTestPssMode = false;
1336
1337     String mDebugApp = null;
1338     boolean mWaitForDebugger = false;
1339     boolean mDebugTransient = false;
1340     String mOrigDebugApp = null;
1341     boolean mOrigWaitForDebugger = false;
1342     boolean mAlwaysFinishActivities = false;
1343     boolean mLenientBackgroundCheck = false;
1344     boolean mForceResizableActivities;
1345     boolean mSupportsMultiWindow;
1346     boolean mSupportsFreeformWindowManagement;
1347     boolean mSupportsPictureInPicture;
1348     Rect mDefaultPinnedStackBounds;
1349     IActivityController mController = null;
1350     boolean mControllerIsAMonkey = false;
1351     String mProfileApp = null;
1352     ProcessRecord mProfileProc = null;
1353     String mProfileFile;
1354     ParcelFileDescriptor mProfileFd;
1355     int mSamplingInterval = 0;
1356     boolean mAutoStopProfiler = false;
1357     int mProfileType = 0;
1358     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1359     String mMemWatchDumpProcName;
1360     String mMemWatchDumpFile;
1361     int mMemWatchDumpPid;
1362     int mMemWatchDumpUid;
1363     String mTrackAllocationApp = null;
1364     String mNativeDebuggingApp = null;
1365
1366     final long[] mTmpLong = new long[2];
1367
1368     static final class ProcessChangeItem {
1369         static final int CHANGE_ACTIVITIES = 1<<0;
1370         static final int CHANGE_PROCESS_STATE = 1<<1;
1371         int changes;
1372         int uid;
1373         int pid;
1374         int processState;
1375         boolean foregroundActivities;
1376     }
1377
1378     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1379     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1380
1381     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1382     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1383
1384     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1385     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1386
1387     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1388     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1389
1390     /**
1391      * Runtime CPU use collection thread.  This object's lock is used to
1392      * perform synchronization with the thread (notifying it to run).
1393      */
1394     final Thread mProcessCpuThread;
1395
1396     /**
1397      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1398      * Must acquire this object's lock when accessing it.
1399      * NOTE: this lock will be held while doing long operations (trawling
1400      * through all processes in /proc), so it should never be acquired by
1401      * any critical paths such as when holding the main activity manager lock.
1402      */
1403     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1404             MONITOR_THREAD_CPU_USAGE);
1405     final AtomicLong mLastCpuTime = new AtomicLong(0);
1406     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1407
1408     long mLastWriteTime = 0;
1409
1410     /**
1411      * Used to retain an update lock when the foreground activity is in
1412      * immersive mode.
1413      */
1414     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1415
1416     /**
1417      * Set to true after the system has finished booting.
1418      */
1419     boolean mBooted = false;
1420
1421     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1422     int mProcessLimitOverride = -1;
1423
1424     WindowManagerService mWindowManager;
1425     final ActivityThread mSystemThread;
1426
1427     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1428         final ProcessRecord mApp;
1429         final int mPid;
1430         final IApplicationThread mAppThread;
1431
1432         AppDeathRecipient(ProcessRecord app, int pid,
1433                 IApplicationThread thread) {
1434             if (DEBUG_ALL) Slog.v(
1435                 TAG, "New death recipient " + this
1436                 + " for thread " + thread.asBinder());
1437             mApp = app;
1438             mPid = pid;
1439             mAppThread = thread;
1440         }
1441
1442         @Override
1443         public void binderDied() {
1444             if (DEBUG_ALL) Slog.v(
1445                 TAG, "Death received in " + this
1446                 + " for thread " + mAppThread.asBinder());
1447             synchronized(ActivityManagerService.this) {
1448                 appDiedLocked(mApp, mPid, mAppThread, true);
1449             }
1450         }
1451     }
1452
1453     static final int SHOW_ERROR_UI_MSG = 1;
1454     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1455     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1456     static final int UPDATE_CONFIGURATION_MSG = 4;
1457     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1458     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1459     static final int SERVICE_TIMEOUT_MSG = 12;
1460     static final int UPDATE_TIME_ZONE = 13;
1461     static final int SHOW_UID_ERROR_UI_MSG = 14;
1462     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1463     static final int PROC_START_TIMEOUT_MSG = 20;
1464     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1465     static final int KILL_APPLICATION_MSG = 22;
1466     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1467     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1468     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1469     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1470     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1471     static final int CLEAR_DNS_CACHE_MSG = 28;
1472     static final int UPDATE_HTTP_PROXY_MSG = 29;
1473     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1474     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1475     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1476     static final int REPORT_MEM_USAGE_MSG = 33;
1477     static final int REPORT_USER_SWITCH_MSG = 34;
1478     static final int CONTINUE_USER_SWITCH_MSG = 35;
1479     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1480     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1481     static final int PERSIST_URI_GRANTS_MSG = 38;
1482     static final int REQUEST_ALL_PSS_MSG = 39;
1483     static final int START_PROFILES_MSG = 40;
1484     static final int UPDATE_TIME = 41;
1485     static final int SYSTEM_USER_START_MSG = 42;
1486     static final int SYSTEM_USER_CURRENT_MSG = 43;
1487     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1488     static final int FINISH_BOOTING_MSG = 45;
1489     static final int START_USER_SWITCH_UI_MSG = 46;
1490     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1491     static final int DISMISS_DIALOG_UI_MSG = 48;
1492     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1493     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1494     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1495     static final int DELETE_DUMPHEAP_MSG = 52;
1496     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1497     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1498     static final int REPORT_TIME_TRACKER_MSG = 55;
1499     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1500     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1501     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1502     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1503     static final int IDLE_UIDS_MSG = 60;
1504     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1505     static final int LOG_STACK_STATE = 62;
1506     static final int VR_MODE_CHANGE_MSG = 63;
1507     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1508     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1509     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1510     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1511     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1512     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1513
1514     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1515     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1516     static final int FIRST_COMPAT_MODE_MSG = 300;
1517     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1518
1519     static ServiceThread sKillThread = null;
1520     static KillHandler sKillHandler = null;
1521
1522     CompatModeDialog mCompatModeDialog;
1523     long mLastMemUsageReportTime = 0;
1524
1525     /**
1526      * Flag whether the current user is a "monkey", i.e. whether
1527      * the UI is driven by a UI automation tool.
1528      */
1529     private boolean mUserIsMonkey;
1530
1531     /** Flag whether the device has a Recents UI */
1532     boolean mHasRecents;
1533
1534     /** The dimensions of the thumbnails in the Recents UI. */
1535     int mThumbnailWidth;
1536     int mThumbnailHeight;
1537     float mFullscreenThumbnailScale;
1538
1539     final ServiceThread mHandlerThread;
1540     final MainHandler mHandler;
1541     final UiHandler mUiHandler;
1542
1543     PackageManagerInternal mPackageManagerInt;
1544
1545     // VoiceInteraction session ID that changes for each new request except when
1546     // being called for multiwindow assist in a single session.
1547     private int mViSessionId = 1000;
1548
1549     final class KillHandler extends Handler {
1550         static final int KILL_PROCESS_GROUP_MSG = 4000;
1551
1552         public KillHandler(Looper looper) {
1553             super(looper, null, true);
1554         }
1555
1556         @Override
1557         public void handleMessage(Message msg) {
1558             switch (msg.what) {
1559                 case KILL_PROCESS_GROUP_MSG:
1560                 {
1561                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1562                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1563                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1564                 }
1565                 break;
1566
1567                 default:
1568                     super.handleMessage(msg);
1569             }
1570         }
1571     }
1572
1573     final class UiHandler extends Handler {
1574         public UiHandler() {
1575             super(com.android.server.UiThread.get().getLooper(), null, true);
1576         }
1577
1578         @Override
1579         public void handleMessage(Message msg) {
1580             switch (msg.what) {
1581             case SHOW_ERROR_UI_MSG: {
1582                 mAppErrors.handleShowAppErrorUi(msg);
1583                 ensureBootCompleted();
1584             } break;
1585             case SHOW_NOT_RESPONDING_UI_MSG: {
1586                 mAppErrors.handleShowAnrUi(msg);
1587                 ensureBootCompleted();
1588             } break;
1589             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1590                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1591                 synchronized (ActivityManagerService.this) {
1592                     ProcessRecord proc = (ProcessRecord) data.get("app");
1593                     if (proc == null) {
1594                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1595                         break;
1596                     }
1597                     if (proc.crashDialog != null) {
1598                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1599                         return;
1600                     }
1601                     AppErrorResult res = (AppErrorResult) data.get("result");
1602                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1603                         Dialog d = new StrictModeViolationDialog(mContext,
1604                                 ActivityManagerService.this, res, proc);
1605                         d.show();
1606                         proc.crashDialog = d;
1607                     } else {
1608                         // The device is asleep, so just pretend that the user
1609                         // saw a crash dialog and hit "force quit".
1610                         res.set(0);
1611                     }
1612                 }
1613                 ensureBootCompleted();
1614             } break;
1615             case SHOW_FACTORY_ERROR_UI_MSG: {
1616                 Dialog d = new FactoryErrorDialog(
1617                     mContext, msg.getData().getCharSequence("msg"));
1618                 d.show();
1619                 ensureBootCompleted();
1620             } break;
1621             case WAIT_FOR_DEBUGGER_UI_MSG: {
1622                 synchronized (ActivityManagerService.this) {
1623                     ProcessRecord app = (ProcessRecord)msg.obj;
1624                     if (msg.arg1 != 0) {
1625                         if (!app.waitedForDebugger) {
1626                             Dialog d = new AppWaitingForDebuggerDialog(
1627                                     ActivityManagerService.this,
1628                                     mContext, app);
1629                             app.waitDialog = d;
1630                             app.waitedForDebugger = true;
1631                             d.show();
1632                         }
1633                     } else {
1634                         if (app.waitDialog != null) {
1635                             app.waitDialog.dismiss();
1636                             app.waitDialog = null;
1637                         }
1638                     }
1639                 }
1640             } break;
1641             case SHOW_UID_ERROR_UI_MSG: {
1642                 if (mShowDialogs) {
1643                     AlertDialog d = new BaseErrorDialog(mContext);
1644                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1645                     d.setCancelable(false);
1646                     d.setTitle(mContext.getText(R.string.android_system_label));
1647                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1648                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1649                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1650                     d.show();
1651                 }
1652             } break;
1653             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1654                 if (mShowDialogs) {
1655                     AlertDialog d = new BaseErrorDialog(mContext);
1656                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                     d.setCancelable(false);
1658                     d.setTitle(mContext.getText(R.string.android_system_label));
1659                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1660                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                     d.show();
1663                 }
1664             } break;
1665             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1666                 synchronized (ActivityManagerService.this) {
1667                     ActivityRecord ar = (ActivityRecord) msg.obj;
1668                     if (mCompatModeDialog != null) {
1669                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1670                                 ar.info.applicationInfo.packageName)) {
1671                             return;
1672                         }
1673                         mCompatModeDialog.dismiss();
1674                         mCompatModeDialog = null;
1675                     }
1676                     if (ar != null && false) {
1677                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1678                                 ar.packageName)) {
1679                             int mode = mCompatModePackages.computeCompatModeLocked(
1680                                     ar.info.applicationInfo);
1681                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1682                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1683                                 mCompatModeDialog = new CompatModeDialog(
1684                                         ActivityManagerService.this, mContext,
1685                                         ar.info.applicationInfo);
1686                                 mCompatModeDialog.show();
1687                             }
1688                         }
1689                     }
1690                 }
1691                 break;
1692             }
1693             case START_USER_SWITCH_UI_MSG: {
1694                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1695                 break;
1696             }
1697             case DISMISS_DIALOG_UI_MSG: {
1698                 final Dialog d = (Dialog) msg.obj;
1699                 d.dismiss();
1700                 break;
1701             }
1702             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1703                 dispatchProcessesChanged();
1704                 break;
1705             }
1706             case DISPATCH_PROCESS_DIED_UI_MSG: {
1707                 final int pid = msg.arg1;
1708                 final int uid = msg.arg2;
1709                 dispatchProcessDied(pid, uid);
1710                 break;
1711             }
1712             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1713                 dispatchUidsChanged();
1714             } break;
1715             }
1716         }
1717     }
1718
1719     final class MainHandler extends Handler {
1720         public MainHandler(Looper looper) {
1721             super(looper, null, true);
1722         }
1723
1724         @Override
1725         public void handleMessage(Message msg) {
1726             switch (msg.what) {
1727             case UPDATE_CONFIGURATION_MSG: {
1728                 final ContentResolver resolver = mContext.getContentResolver();
1729                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1730                         msg.arg1);
1731             } break;
1732             case GC_BACKGROUND_PROCESSES_MSG: {
1733                 synchronized (ActivityManagerService.this) {
1734                     performAppGcsIfAppropriateLocked();
1735                 }
1736             } break;
1737             case SERVICE_TIMEOUT_MSG: {
1738                 if (mDidDexOpt) {
1739                     mDidDexOpt = false;
1740                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1741                     nmsg.obj = msg.obj;
1742                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1743                     return;
1744                 }
1745                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1746             } break;
1747             case UPDATE_TIME_ZONE: {
1748                 synchronized (ActivityManagerService.this) {
1749                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                         ProcessRecord r = mLruProcesses.get(i);
1751                         if (r.thread != null) {
1752                             try {
1753                                 r.thread.updateTimeZone();
1754                             } catch (RemoteException ex) {
1755                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1756                             }
1757                         }
1758                     }
1759                 }
1760             } break;
1761             case CLEAR_DNS_CACHE_MSG: {
1762                 synchronized (ActivityManagerService.this) {
1763                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764                         ProcessRecord r = mLruProcesses.get(i);
1765                         if (r.thread != null) {
1766                             try {
1767                                 r.thread.clearDnsCache();
1768                             } catch (RemoteException ex) {
1769                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1770                             }
1771                         }
1772                     }
1773                 }
1774             } break;
1775             case UPDATE_HTTP_PROXY_MSG: {
1776                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1777                 String host = "";
1778                 String port = "";
1779                 String exclList = "";
1780                 Uri pacFileUrl = Uri.EMPTY;
1781                 if (proxy != null) {
1782                     host = proxy.getHost();
1783                     port = Integer.toString(proxy.getPort());
1784                     exclList = proxy.getExclusionListAsString();
1785                     pacFileUrl = proxy.getPacFileUrl();
1786                 }
1787                 synchronized (ActivityManagerService.this) {
1788                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                         ProcessRecord r = mLruProcesses.get(i);
1790                         if (r.thread != null) {
1791                             try {
1792                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1793                             } catch (RemoteException ex) {
1794                                 Slog.w(TAG, "Failed to update http proxy for: " +
1795                                         r.info.processName);
1796                             }
1797                         }
1798                     }
1799                 }
1800             } break;
1801             case PROC_START_TIMEOUT_MSG: {
1802                 if (mDidDexOpt) {
1803                     mDidDexOpt = false;
1804                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1805                     nmsg.obj = msg.obj;
1806                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1807                     return;
1808                 }
1809                 ProcessRecord app = (ProcessRecord)msg.obj;
1810                 synchronized (ActivityManagerService.this) {
1811                     processStartTimedOutLocked(app);
1812                 }
1813             } break;
1814             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1815                 ProcessRecord app = (ProcessRecord)msg.obj;
1816                 synchronized (ActivityManagerService.this) {
1817                     processContentProviderPublishTimedOutLocked(app);
1818                 }
1819             } break;
1820             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1821                 synchronized (ActivityManagerService.this) {
1822                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1823                 }
1824             } break;
1825             case KILL_APPLICATION_MSG: {
1826                 synchronized (ActivityManagerService.this) {
1827                     int appid = msg.arg1;
1828                     boolean restart = (msg.arg2 == 1);
1829                     Bundle bundle = (Bundle)msg.obj;
1830                     String pkg = bundle.getString("pkg");
1831                     String reason = bundle.getString("reason");
1832                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1833                             false, UserHandle.USER_ALL, reason);
1834                 }
1835             } break;
1836             case FINALIZE_PENDING_INTENT_MSG: {
1837                 ((PendingIntentRecord)msg.obj).completeFinalize();
1838             } break;
1839             case POST_HEAVY_NOTIFICATION_MSG: {
1840                 INotificationManager inm = NotificationManager.getService();
1841                 if (inm == null) {
1842                     return;
1843                 }
1844
1845                 ActivityRecord root = (ActivityRecord)msg.obj;
1846                 ProcessRecord process = root.app;
1847                 if (process == null) {
1848                     return;
1849                 }
1850
1851                 try {
1852                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1853                     String text = mContext.getString(R.string.heavy_weight_notification,
1854                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1855                     Notification notification = new Notification.Builder(context)
1856                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1857                             .setWhen(0)
1858                             .setOngoing(true)
1859                             .setTicker(text)
1860                             .setColor(mContext.getColor(
1861                                     com.android.internal.R.color.system_notification_accent_color))
1862                             .setContentTitle(text)
1863                             .setContentText(
1864                                     mContext.getText(R.string.heavy_weight_notification_detail))
1865                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1866                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1867                                     new UserHandle(root.userId)))
1868                             .build();
1869                     try {
1870                         int[] outId = new int[1];
1871                         inm.enqueueNotificationWithTag("android", "android", null,
1872                                 R.string.heavy_weight_notification,
1873                                 notification, outId, root.userId);
1874                     } catch (RuntimeException e) {
1875                         Slog.w(ActivityManagerService.TAG,
1876                                 "Error showing notification for heavy-weight app", e);
1877                     } catch (RemoteException e) {
1878                     }
1879                 } catch (NameNotFoundException e) {
1880                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1881                 }
1882             } break;
1883             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1884                 INotificationManager inm = NotificationManager.getService();
1885                 if (inm == null) {
1886                     return;
1887                 }
1888                 try {
1889                     inm.cancelNotificationWithTag("android", null,
1890                             R.string.heavy_weight_notification,  msg.arg1);
1891                 } catch (RuntimeException e) {
1892                     Slog.w(ActivityManagerService.TAG,
1893                             "Error canceling notification for service", e);
1894                 } catch (RemoteException e) {
1895                 }
1896             } break;
1897             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1898                 synchronized (ActivityManagerService.this) {
1899                     checkExcessivePowerUsageLocked(true);
1900                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1902                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1903                 }
1904             } break;
1905             case REPORT_MEM_USAGE_MSG: {
1906                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1907                 Thread thread = new Thread() {
1908                     @Override public void run() {
1909                         reportMemUsage(memInfos);
1910                     }
1911                 };
1912                 thread.start();
1913                 break;
1914             }
1915             case REPORT_USER_SWITCH_MSG: {
1916                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1917                 break;
1918             }
1919             case CONTINUE_USER_SWITCH_MSG: {
1920                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1921                 break;
1922             }
1923             case USER_SWITCH_TIMEOUT_MSG: {
1924                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1925                 break;
1926             }
1927             case IMMERSIVE_MODE_LOCK_MSG: {
1928                 final boolean nextState = (msg.arg1 != 0);
1929                 if (mUpdateLock.isHeld() != nextState) {
1930                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1931                             "Applying new update lock state '" + nextState
1932                             + "' for " + (ActivityRecord)msg.obj);
1933                     if (nextState) {
1934                         mUpdateLock.acquire();
1935                     } else {
1936                         mUpdateLock.release();
1937                     }
1938                 }
1939                 break;
1940             }
1941             case PERSIST_URI_GRANTS_MSG: {
1942                 writeGrantedUriPermissions();
1943                 break;
1944             }
1945             case REQUEST_ALL_PSS_MSG: {
1946                 synchronized (ActivityManagerService.this) {
1947                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1948                 }
1949                 break;
1950             }
1951             case START_PROFILES_MSG: {
1952                 synchronized (ActivityManagerService.this) {
1953                     mUserController.startProfilesLocked();
1954                 }
1955                 break;
1956             }
1957             case UPDATE_TIME: {
1958                 synchronized (ActivityManagerService.this) {
1959                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1960                         ProcessRecord r = mLruProcesses.get(i);
1961                         if (r.thread != null) {
1962                             try {
1963                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1964                             } catch (RemoteException ex) {
1965                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1966                             }
1967                         }
1968                     }
1969                 }
1970                 break;
1971             }
1972             case SYSTEM_USER_START_MSG: {
1973                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1974                         Integer.toString(msg.arg1), msg.arg1);
1975                 mSystemServiceManager.startUser(msg.arg1);
1976                 break;
1977             }
1978             case SYSTEM_USER_UNLOCK_MSG: {
1979                 final int userId = msg.arg1;
1980                 mSystemServiceManager.unlockUser(userId);
1981                 synchronized (ActivityManagerService.this) {
1982                     mRecentTasks.loadUserRecentsLocked(userId);
1983                 }
1984                 if (userId == UserHandle.USER_SYSTEM) {
1985                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1986                 }
1987                 installEncryptionUnawareProviders(userId);
1988                 mUserController.finishUserUnlocked((UserState) msg.obj);
1989                 break;
1990             }
1991             case SYSTEM_USER_CURRENT_MSG: {
1992                 mBatteryStatsService.noteEvent(
1993                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1994                         Integer.toString(msg.arg2), msg.arg2);
1995                 mBatteryStatsService.noteEvent(
1996                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1997                         Integer.toString(msg.arg1), msg.arg1);
1998                 mSystemServiceManager.switchUser(msg.arg1);
1999                 break;
2000             }
2001             case ENTER_ANIMATION_COMPLETE_MSG: {
2002                 synchronized (ActivityManagerService.this) {
2003                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2004                     if (r != null && r.app != null && r.app.thread != null) {
2005                         try {
2006                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2007                         } catch (RemoteException e) {
2008                         }
2009                     }
2010                 }
2011                 break;
2012             }
2013             case FINISH_BOOTING_MSG: {
2014                 if (msg.arg1 != 0) {
2015                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2016                     finishBooting();
2017                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2018                 }
2019                 if (msg.arg2 != 0) {
2020                     enableScreenAfterBoot();
2021                 }
2022                 break;
2023             }
2024             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2025                 try {
2026                     Locale l = (Locale) msg.obj;
2027                     IBinder service = ServiceManager.getService("mount");
2028                     IMountService mountService = IMountService.Stub.asInterface(service);
2029                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2030                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2031                 } catch (RemoteException e) {
2032                     Log.e(TAG, "Error storing locale for decryption UI", e);
2033                 }
2034                 break;
2035             }
2036             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2037                 synchronized (ActivityManagerService.this) {
2038                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                         try {
2040                             // Make a one-way callback to the listener
2041                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2042                         } catch (RemoteException e){
2043                             // Handled by the RemoteCallbackList
2044                         }
2045                     }
2046                     mTaskStackListeners.finishBroadcast();
2047                 }
2048                 break;
2049             }
2050             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2051                 synchronized (ActivityManagerService.this) {
2052                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                         try {
2054                             // Make a one-way callback to the listener
2055                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2056                         } catch (RemoteException e){
2057                             // Handled by the RemoteCallbackList
2058                         }
2059                     }
2060                     mTaskStackListeners.finishBroadcast();
2061                 }
2062                 break;
2063             }
2064             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2065                 synchronized (ActivityManagerService.this) {
2066                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                         try {
2068                             // Make a one-way callback to the listener
2069                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2070                         } catch (RemoteException e){
2071                             // Handled by the RemoteCallbackList
2072                         }
2073                     }
2074                     mTaskStackListeners.finishBroadcast();
2075                 }
2076                 break;
2077             }
2078             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2079                 synchronized (ActivityManagerService.this) {
2080                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                         try {
2082                             // Make a one-way callback to the listener
2083                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2084                         } catch (RemoteException e){
2085                             // Handled by the RemoteCallbackList
2086                         }
2087                     }
2088                     mTaskStackListeners.finishBroadcast();
2089                 }
2090                 break;
2091             }
2092             case NOTIFY_FORCED_RESIZABLE_MSG: {
2093                 synchronized (ActivityManagerService.this) {
2094                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                         try {
2096                             // Make a one-way callback to the listener
2097                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2098                                     (String) msg.obj, msg.arg1);
2099                         } catch (RemoteException e){
2100                             // Handled by the RemoteCallbackList
2101                         }
2102                     }
2103                     mTaskStackListeners.finishBroadcast();
2104                 }
2105                 break;
2106             }
2107                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2108                     synchronized (ActivityManagerService.this) {
2109                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                             try {
2111                                 // Make a one-way callback to the listener
2112                                 mTaskStackListeners.getBroadcastItem(i)
2113                                         .onActivityDismissingDockedStack();
2114                             } catch (RemoteException e){
2115                                 // Handled by the RemoteCallbackList
2116                             }
2117                         }
2118                         mTaskStackListeners.finishBroadcast();
2119                     }
2120                     break;
2121                 }
2122             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2123                 final int uid = msg.arg1;
2124                 final byte[] firstPacket = (byte[]) msg.obj;
2125
2126                 synchronized (mPidsSelfLocked) {
2127                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2128                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2129                         if (p.uid == uid) {
2130                             try {
2131                                 p.thread.notifyCleartextNetwork(firstPacket);
2132                             } catch (RemoteException ignored) {
2133                             }
2134                         }
2135                     }
2136                 }
2137                 break;
2138             }
2139             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2140                 final String procName;
2141                 final int uid;
2142                 final long memLimit;
2143                 final String reportPackage;
2144                 synchronized (ActivityManagerService.this) {
2145                     procName = mMemWatchDumpProcName;
2146                     uid = mMemWatchDumpUid;
2147                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2148                     if (val == null) {
2149                         val = mMemWatchProcesses.get(procName, 0);
2150                     }
2151                     if (val != null) {
2152                         memLimit = val.first;
2153                         reportPackage = val.second;
2154                     } else {
2155                         memLimit = 0;
2156                         reportPackage = null;
2157                     }
2158                 }
2159                 if (procName == null) {
2160                     return;
2161                 }
2162
2163                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2164                         "Showing dump heap notification from " + procName + "/" + uid);
2165
2166                 INotificationManager inm = NotificationManager.getService();
2167                 if (inm == null) {
2168                     return;
2169                 }
2170
2171                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2172
2173
2174                 Intent deleteIntent = new Intent();
2175                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2176                 Intent intent = new Intent();
2177                 intent.setClassName("android", DumpHeapActivity.class.getName());
2178                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2179                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2180                 if (reportPackage != null) {
2181                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2182                 }
2183                 int userId = UserHandle.getUserId(uid);
2184                 Notification notification = new Notification.Builder(mContext)
2185                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2186                         .setWhen(0)
2187                         .setOngoing(true)
2188                         .setAutoCancel(true)
2189                         .setTicker(text)
2190                         .setColor(mContext.getColor(
2191                                 com.android.internal.R.color.system_notification_accent_color))
2192                         .setContentTitle(text)
2193                         .setContentText(
2194                                 mContext.getText(R.string.dump_heap_notification_detail))
2195                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2196                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2197                                 new UserHandle(userId)))
2198                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2199                                 deleteIntent, 0, UserHandle.SYSTEM))
2200                         .build();
2201
2202                 try {
2203                     int[] outId = new int[1];
2204                     inm.enqueueNotificationWithTag("android", "android", null,
2205                             R.string.dump_heap_notification,
2206                             notification, outId, userId);
2207                 } catch (RuntimeException e) {
2208                     Slog.w(ActivityManagerService.TAG,
2209                             "Error showing notification for dump heap", e);
2210                 } catch (RemoteException e) {
2211                 }
2212             } break;
2213             case DELETE_DUMPHEAP_MSG: {
2214                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2215                         DumpHeapActivity.JAVA_URI,
2216                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2217                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2218                         UserHandle.myUserId());
2219                 synchronized (ActivityManagerService.this) {
2220                     mMemWatchDumpFile = null;
2221                     mMemWatchDumpProcName = null;
2222                     mMemWatchDumpPid = -1;
2223                     mMemWatchDumpUid = -1;
2224                 }
2225             } break;
2226             case FOREGROUND_PROFILE_CHANGED_MSG: {
2227                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2228             } break;
2229             case REPORT_TIME_TRACKER_MSG: {
2230                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2231                 tracker.deliverResult(mContext);
2232             } break;
2233             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2234                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2235             } break;
2236             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2237                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2238                 try {
2239                     connection.shutdown();
2240                 } catch (RemoteException e) {
2241                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2242                 }
2243                 // Only a UiAutomation can set this flag and now that
2244                 // it is finished we make sure it is reset to its default.
2245                 mUserIsMonkey = false;
2246             } break;
2247             case APP_BOOST_DEACTIVATE_MSG: {
2248                 synchronized(ActivityManagerService.this) {
2249                     if (mIsBoosted) {
2250                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2251                             nativeMigrateFromBoost();
2252                             mIsBoosted = false;
2253                             mBoostStartTime = 0;
2254                         } else {
2255                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2256                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2257                         }
2258                     }
2259                 }
2260             } break;
2261             case IDLE_UIDS_MSG: {
2262                 idleUids();
2263             } break;
2264             case LOG_STACK_STATE: {
2265                 synchronized (ActivityManagerService.this) {
2266                     mStackSupervisor.logStackState();
2267                 }
2268             } break;
2269             case VR_MODE_CHANGE_MSG: {
2270                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2271                 final ActivityRecord r = (ActivityRecord) msg.obj;
2272                 boolean vrMode;
2273                 ComponentName requestedPackage;
2274                 ComponentName callingPackage;
2275                 int userId;
2276                 synchronized (ActivityManagerService.this) {
2277                     vrMode = r.requestedVrComponent != null;
2278                     requestedPackage = r.requestedVrComponent;
2279                     userId = r.userId;
2280                     callingPackage = r.info.getComponentName();
2281                     if (mInVrMode != vrMode) {
2282                         mInVrMode = vrMode;
2283                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2284                     }
2285                 }
2286                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2287             } break;
2288             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2289                 final ActivityRecord r = (ActivityRecord) msg.obj;
2290                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2291                 if (needsVrMode) {
2292                     VrManagerInternal vrService =
2293                             LocalServices.getService(VrManagerInternal.class);
2294                     boolean enable = msg.arg1 == 1;
2295                     vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2296                             r.info.getComponentName());
2297                 }
2298             } break;
2299             }
2300         }
2301     };
2302
2303     static final int COLLECT_PSS_BG_MSG = 1;
2304
2305     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306         @Override
2307         public void handleMessage(Message msg) {
2308             switch (msg.what) {
2309             case COLLECT_PSS_BG_MSG: {
2310                 long start = SystemClock.uptimeMillis();
2311                 MemInfoReader memInfo = null;
2312                 synchronized (ActivityManagerService.this) {
2313                     if (mFullPssPending) {
2314                         mFullPssPending = false;
2315                         memInfo = new MemInfoReader();
2316                     }
2317                 }
2318                 if (memInfo != null) {
2319                     updateCpuStatsNow();
2320                     long nativeTotalPss = 0;
2321                     synchronized (mProcessCpuTracker) {
2322                         final int N = mProcessCpuTracker.countStats();
2323                         for (int j=0; j<N; j++) {
2324                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                 // This is definitely an application process; skip it.
2327                                 continue;
2328                             }
2329                             synchronized (mPidsSelfLocked) {
2330                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                     // This is one of our own processes; skip it.
2332                                     continue;
2333                                 }
2334                             }
2335                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                         }
2337                     }
2338                     memInfo.readMemInfo();
2339                     synchronized (ActivityManagerService.this) {
2340                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                 + (SystemClock.uptimeMillis()-start) + "ms");
2342                         final long cachedKb = memInfo.getCachedSizeKb();
2343                         final long freeKb = memInfo.getFreeSizeKb();
2344                         final long zramKb = memInfo.getZramTotalSizeKb();
2345                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                 kernelKb*1024, nativeTotalPss*1024);
2348                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                 nativeTotalPss);
2350                     }
2351                 }
2352
2353                 int num = 0;
2354                 long[] tmp = new long[2];
2355                 do {
2356                     ProcessRecord proc;
2357                     int procState;
2358                     int pid;
2359                     long lastPssTime;
2360                     synchronized (ActivityManagerService.this) {
2361                         if (mPendingPssProcesses.size() <= 0) {
2362                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                     "Collected PSS of " + num + " processes in "
2364                                     + (SystemClock.uptimeMillis() - start) + "ms");
2365                             mPendingPssProcesses.clear();
2366                             return;
2367                         }
2368                         proc = mPendingPssProcesses.remove(0);
2369                         procState = proc.pssProcState;
2370                         lastPssTime = proc.lastPssTime;
2371                         if (proc.thread != null && procState == proc.setProcState
2372                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                         < SystemClock.uptimeMillis()) {
2374                             pid = proc.pid;
2375                         } else {
2376                             proc = null;
2377                             pid = 0;
2378                         }
2379                     }
2380                     if (proc != null) {
2381                         long pss = Debug.getPss(pid, tmp, null);
2382                         synchronized (ActivityManagerService.this) {
2383                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                 num++;
2386                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                         SystemClock.uptimeMillis());
2388                             }
2389                         }
2390                     }
2391                 } while (true);
2392             }
2393             }
2394         }
2395     };
2396
2397     public void setSystemProcess() {
2398         try {
2399             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401             ServiceManager.addService("meminfo", new MemBinder(this));
2402             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403             ServiceManager.addService("dbinfo", new DbBinder(this));
2404             if (MONITOR_CPU_USAGE) {
2405                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406             }
2407             ServiceManager.addService("permission", new PermissionController(this));
2408             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414             synchronized (this) {
2415                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                 app.persistent = true;
2417                 app.pid = MY_PID;
2418                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                 synchronized (mPidsSelfLocked) {
2421                     mPidsSelfLocked.put(app.pid, app);
2422                 }
2423                 updateLruProcessLocked(app, false, null);
2424                 updateOomAdjLocked();
2425             }
2426         } catch (PackageManager.NameNotFoundException e) {
2427             throw new RuntimeException(
2428                     "Unable to find android system package", e);
2429         }
2430     }
2431
2432     public void setWindowManager(WindowManagerService wm) {
2433         mWindowManager = wm;
2434         mStackSupervisor.setWindowManager(wm);
2435         mActivityStarter.setWindowManager(wm);
2436     }
2437
2438     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439         mUsageStatsService = usageStatsManager;
2440     }
2441
2442     public void startObservingNativeCrashes() {
2443         final NativeCrashListener ncl = new NativeCrashListener(this);
2444         ncl.start();
2445     }
2446
2447     public IAppOpsService getAppOpsService() {
2448         return mAppOpsService;
2449     }
2450
2451     static class MemBinder extends Binder {
2452         ActivityManagerService mActivityManagerService;
2453         MemBinder(ActivityManagerService activityManagerService) {
2454             mActivityManagerService = activityManagerService;
2455         }
2456
2457         @Override
2458         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                     != PackageManager.PERMISSION_GRANTED) {
2461                 pw.println("Permission Denial: can't dump meminfo from from pid="
2462                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                         + " without permission " + android.Manifest.permission.DUMP);
2464                 return;
2465             }
2466
2467             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468         }
2469     }
2470
2471     static class GraphicsBinder extends Binder {
2472         ActivityManagerService mActivityManagerService;
2473         GraphicsBinder(ActivityManagerService activityManagerService) {
2474             mActivityManagerService = activityManagerService;
2475         }
2476
2477         @Override
2478         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                     != PackageManager.PERMISSION_GRANTED) {
2481                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                         + " without permission " + android.Manifest.permission.DUMP);
2484                 return;
2485             }
2486
2487             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488         }
2489     }
2490
2491     static class DbBinder extends Binder {
2492         ActivityManagerService mActivityManagerService;
2493         DbBinder(ActivityManagerService activityManagerService) {
2494             mActivityManagerService = activityManagerService;
2495         }
2496
2497         @Override
2498         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                     != PackageManager.PERMISSION_GRANTED) {
2501                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                         + " without permission " + android.Manifest.permission.DUMP);
2504                 return;
2505             }
2506
2507             mActivityManagerService.dumpDbInfo(fd, pw, args);
2508         }
2509     }
2510
2511     static class CpuBinder extends Binder {
2512         ActivityManagerService mActivityManagerService;
2513         CpuBinder(ActivityManagerService activityManagerService) {
2514             mActivityManagerService = activityManagerService;
2515         }
2516
2517         @Override
2518         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                     != PackageManager.PERMISSION_GRANTED) {
2521                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                         + " without permission " + android.Manifest.permission.DUMP);
2524                 return;
2525             }
2526
2527             synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                         SystemClock.uptimeMillis()));
2531             }
2532         }
2533     }
2534
2535     public static final class Lifecycle extends SystemService {
2536         private final ActivityManagerService mService;
2537
2538         public Lifecycle(Context context) {
2539             super(context);
2540             mService = new ActivityManagerService(context);
2541         }
2542
2543         @Override
2544         public void onStart() {
2545             mService.start();
2546         }
2547
2548         public ActivityManagerService getService() {
2549             return mService;
2550         }
2551     }
2552
2553     // Note: This method is invoked on the main thread but may need to attach various
2554     // handlers to other threads.  So take care to be explicit about the looper.
2555     public ActivityManagerService(Context systemContext) {
2556         mContext = systemContext;
2557         mFactoryTest = FactoryTest.getMode();
2558         mSystemThread = ActivityThread.currentActivityThread();
2559
2560         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562         mHandlerThread = new ServiceThread(TAG,
2563                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564         mHandlerThread.start();
2565         mHandler = new MainHandler(mHandlerThread.getLooper());
2566         mUiHandler = new UiHandler();
2567
2568         /* static; one-time init here */
2569         if (sKillHandler == null) {
2570             sKillThread = new ServiceThread(TAG + ":kill",
2571                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572             sKillThread.start();
2573             sKillHandler = new KillHandler(sKillThread.getLooper());
2574         }
2575
2576         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                 "foreground", BROADCAST_FG_TIMEOUT, false);
2578         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                 "background", BROADCAST_BG_TIMEOUT, true);
2580         mBroadcastQueues[0] = mFgBroadcastQueue;
2581         mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583         mServices = new ActiveServices(this);
2584         mProviderMap = new ProviderMap(this);
2585         mAppErrors = new AppErrors(mContext, this);
2586
2587         // TODO: Move creation of battery stats service outside of activity manager service.
2588         File dataDir = Environment.getDataDirectory();
2589         File systemDir = new File(dataDir, "system");
2590         systemDir.mkdirs();
2591         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592         mBatteryStatsService.getActiveStatistics().readLocked();
2593         mBatteryStatsService.scheduleWriteToDisk();
2594         mOnBattery = DEBUG_POWER ? true
2595                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596         mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                 new IAppOpsCallback.Stub() {
2603                     @Override public void opChanged(int op, int uid, String packageName) {
2604                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                             if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                     != AppOpsManager.MODE_ALLOWED) {
2607                                 runInBackgroundDisabled(uid);
2608                             }
2609                         }
2610                     }
2611                 });
2612
2613         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615         mUserController = new UserController(this);
2616
2617         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622         mConfiguration.setToDefaults();
2623         mConfiguration.setLocales(LocaleList.getDefault());
2624
2625         mConfigurationSeq = mConfiguration.seq = 1;
2626         mProcessCpuTracker.init();
2627
2628         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630         mStackSupervisor = new ActivityStackSupervisor(this);
2631         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634         mProcessCpuThread = new Thread("CpuTracker") {
2635             @Override
2636             public void run() {
2637                 while (true) {
2638                     try {
2639                         try {
2640                             synchronized(this) {
2641                                 final long now = SystemClock.uptimeMillis();
2642                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                 //        + ", write delay=" + nextWriteDelay);
2646                                 if (nextWriteDelay < nextCpuDelay) {
2647                                     nextCpuDelay = nextWriteDelay;
2648                                 }
2649                                 if (nextCpuDelay > 0) {
2650                                     mProcessCpuMutexFree.set(true);
2651                                     this.wait(nextCpuDelay);
2652                                 }
2653                             }
2654                         } catch (InterruptedException e) {
2655                         }
2656                         updateCpuStatsNow();
2657                     } catch (Exception e) {
2658                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                     }
2660                 }
2661             }
2662         };
2663
2664         Watchdog.getInstance().addMonitor(this);
2665         Watchdog.getInstance().addThread(mHandler);
2666     }
2667
2668     public void setSystemServiceManager(SystemServiceManager mgr) {
2669         mSystemServiceManager = mgr;
2670     }
2671
2672     public void setInstaller(Installer installer) {
2673         mInstaller = installer;
2674     }
2675
2676     private void start() {
2677         Process.removeAllProcessGroups();
2678         mProcessCpuThread.start();
2679
2680         mBatteryStatsService.publish(mContext);
2681         mAppOpsService.publish(mContext);
2682         Slog.d("AppOps", "AppOpsService published");
2683         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684     }
2685
2686     void onUserStoppedLocked(int userId) {
2687         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688     }
2689
2690     public void initPowerManagement() {
2691         mStackSupervisor.initPowerManagement();
2692         mBatteryStatsService.initPowerManagement();
2693         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696         mVoiceWakeLock.setReferenceCounted(false);
2697     }
2698
2699     @Override
2700     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701             throws RemoteException {
2702         if (code == SYSPROPS_TRANSACTION) {
2703             // We need to tell all apps about the system property change.
2704             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705             synchronized(this) {
2706                 final int NP = mProcessNames.getMap().size();
2707                 for (int ip=0; ip<NP; ip++) {
2708                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                     final int NA = apps.size();
2710                     for (int ia=0; ia<NA; ia++) {
2711                         ProcessRecord app = apps.valueAt(ia);
2712                         if (app.thread != null) {
2713                             procs.add(app.thread.asBinder());
2714                         }
2715                     }
2716                 }
2717             }
2718
2719             int N = procs.size();
2720             for (int i=0; i<N; i++) {
2721                 Parcel data2 = Parcel.obtain();
2722                 try {
2723                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                 } catch (RemoteException e) {
2725                 }
2726                 data2.recycle();
2727             }
2728         }
2729         try {
2730             return super.onTransact(code, data, reply, flags);
2731         } catch (RuntimeException e) {
2732             // The activity manager only throws security exceptions, so let's
2733             // log all others.
2734             if (!(e instanceof SecurityException)) {
2735                 Slog.wtf(TAG, "Activity Manager Crash", e);
2736             }
2737             throw e;
2738         }
2739     }
2740
2741     void updateCpuStats() {
2742         final long now = SystemClock.uptimeMillis();
2743         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744             return;
2745         }
2746         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747             synchronized (mProcessCpuThread) {
2748                 mProcessCpuThread.notify();
2749             }
2750         }
2751     }
2752
2753     void updateCpuStatsNow() {
2754         synchronized (mProcessCpuTracker) {
2755             mProcessCpuMutexFree.set(false);
2756             final long now = SystemClock.uptimeMillis();
2757             boolean haveNewCpuStats = false;
2758
2759             if (MONITOR_CPU_USAGE &&
2760                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                 mLastCpuTime.set(now);
2762                 mProcessCpuTracker.update();
2763                 if (mProcessCpuTracker.hasGoodLastStats()) {
2764                     haveNewCpuStats = true;
2765                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                     //Slog.i(TAG, "Total CPU usage: "
2767                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                     // Slog the cpu usage if the property is set.
2770                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                         int user = mProcessCpuTracker.getLastUserTime();
2772                         int system = mProcessCpuTracker.getLastSystemTime();
2773                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                         int irq = mProcessCpuTracker.getLastIrqTime();
2775                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                         int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                         int total = user + system + iowait + irq + softIrq + idle;
2779                         if (total == 0) total = 1;
2780
2781                         EventLog.writeEvent(EventLogTags.CPU,
2782                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                 (user * 100) / total,
2784                                 (system * 100) / total,
2785                                 (iowait * 100) / total,
2786                                 (irq * 100) / total,
2787                                 (softIrq * 100) / total);
2788                     }
2789                 }
2790             }
2791
2792             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793             synchronized(bstats) {
2794                 synchronized(mPidsSelfLocked) {
2795                     if (haveNewCpuStats) {
2796                         if (bstats.startAddingCpuLocked()) {
2797                             int totalUTime = 0;
2798                             int totalSTime = 0;
2799                             final int N = mProcessCpuTracker.countStats();
2800                             for (int i=0; i<N; i++) {
2801                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                 if (!st.working) {
2803                                     continue;
2804                                 }
2805                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                 totalUTime += st.rel_utime;
2807                                 totalSTime += st.rel_stime;
2808                                 if (pr != null) {
2809                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                     if (ps == null || !ps.isActive()) {
2811                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                 pr.info.uid, pr.processName);
2813                                     }
2814                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                 } else {
2817                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                     if (ps == null || !ps.isActive()) {
2819                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                 bstats.mapUid(st.uid), st.name);
2821                                     }
2822                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                 }
2824                             }
2825                             final int userTime = mProcessCpuTracker.getLastUserTime();
2826                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                         }
2834                     }
2835                 }
2836
2837                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                     mLastWriteTime = now;
2839                     mBatteryStatsService.scheduleWriteToDisk();
2840                 }
2841             }
2842         }
2843     }
2844
2845     @Override
2846     public void batteryNeedsCpuUpdate() {
2847         updateCpuStatsNow();
2848     }
2849
2850     @Override
2851     public void batteryPowerChanged(boolean onBattery) {
2852         // When plugging in, update the CPU stats first before changing
2853         // the plug state.
2854         updateCpuStatsNow();
2855         synchronized (this) {
2856             synchronized(mPidsSelfLocked) {
2857                 mOnBattery = DEBUG_POWER ? true : onBattery;
2858             }
2859         }
2860     }
2861
2862     @Override
2863     public void batterySendBroadcast(Intent intent) {
2864         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                 AppOpsManager.OP_NONE, null, false, false,
2866                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867     }
2868
2869     /**
2870      * Initialize the application bind args. These are passed to each
2871      * process when the bindApplication() IPC is sent to the process. They're
2872      * lazily setup to make sure the services are running when they're asked for.
2873      */
2874     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875         if (mAppBindArgs == null) {
2876             mAppBindArgs = new HashMap<>();
2877
2878             // Isolated processes won't get this optimization, so that we don't
2879             // violate the rules about which services they have access to.
2880             if (!isolated) {
2881                 // Setup the application init args
2882                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                 mAppBindArgs.put(Context.ALARM_SERVICE,
2885                         ServiceManager.getService(Context.ALARM_SERVICE));
2886             }
2887         }
2888         return mAppBindArgs;
2889     }
2890
2891     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892         if (r == null || mFocusedActivity == r) {
2893             return false;
2894         }
2895
2896         if (!r.isFocusable()) {
2897             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898             return false;
2899         }
2900
2901         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906         mDoingSetFocusedActivity = true;
2907
2908         final ActivityRecord last = mFocusedActivity;
2909         mFocusedActivity = r;
2910         if (r.task.isApplicationTask()) {
2911             if (mCurAppTimeTracker != r.appTimeTracker) {
2912                 // We are switching app tracking.  Complete the current one.
2913                 if (mCurAppTimeTracker != null) {
2914                     mCurAppTimeTracker.stop();
2915                     mHandler.obtainMessage(
2916                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                     mCurAppTimeTracker = null;
2919                 }
2920                 if (r.appTimeTracker != null) {
2921                     mCurAppTimeTracker = r.appTimeTracker;
2922                     startTimeTrackingFocusedActivityLocked();
2923                 }
2924             } else {
2925                 startTimeTrackingFocusedActivityLocked();
2926             }
2927         } else {
2928             r.appTimeTracker = null;
2929         }
2930         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931         // TODO: Probably not, because we don't want to resume voice on switching
2932         // back to this activity
2933         if (r.task.voiceInteractor != null) {
2934             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935         } else {
2936             finishRunningVoiceLocked();
2937             IVoiceInteractionSession session;
2938             if (last != null && ((session = last.task.voiceSession) != null
2939                     || (session = last.voiceSession) != null)) {
2940                 // We had been in a voice interaction session, but now focused has
2941                 // move to something different.  Just finish the session, we can't
2942                 // return to it and retain the proper state and synchronization with
2943                 // the voice interaction service.
2944                 finishVoiceTask(session);
2945             }
2946         }
2947         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948             mWindowManager.setFocusedApp(r.appToken, true);
2949         }
2950         applyUpdateLockStateLocked(r);
2951         applyUpdateVrModeLocked(r);
2952         if (mFocusedActivity.userId != mLastFocusedUserId) {
2953             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954             mHandler.obtainMessage(
2955                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956             mLastFocusedUserId = mFocusedActivity.userId;
2957         }
2958
2959         // Log a warning if the focused app is changed during the process. This could
2960         // indicate a problem of the focus setting logic!
2961         if (mFocusedActivity != r) Slog.w(TAG,
2962                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965         EventLogTags.writeAmFocusedActivity(
2966                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                 reason);
2969         return true;
2970     }
2971
2972     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973         if (mFocusedActivity != goingAway) {
2974             return;
2975         }
2976
2977         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978         if (focusedStack != null) {
2979             final ActivityRecord top = focusedStack.topActivity();
2980             if (top != null && top.userId != mLastFocusedUserId) {
2981                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                 mHandler.sendMessage(
2983                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                 mLastFocusedUserId = top.userId;
2985             }
2986         }
2987
2988         // Try to move focus to another activity if possible.
2989         if (setFocusedActivityLocked(
2990                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991             return;
2992         }
2993
2994         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996         mFocusedActivity = null;
2997         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998     }
2999
3000     @Override
3001     public void setFocusedStack(int stackId) {
3002         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004         final long callingId = Binder.clearCallingIdentity();
3005         try {
3006             synchronized (this) {
3007                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                 if (stack == null) {
3009                     return;
3010                 }
3011                 final ActivityRecord r = stack.topRunningActivityLocked();
3012                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                 }
3015             }
3016         } finally {
3017             Binder.restoreCallingIdentity(callingId);
3018         }
3019     }
3020
3021     @Override
3022     public void setFocusedTask(int taskId) {
3023         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025         final long callingId = Binder.clearCallingIdentity();
3026         try {
3027             synchronized (this) {
3028                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                 if (task == null) {
3030                     return;
3031                 }
3032                 final ActivityRecord r = task.topRunningActivityLocked();
3033                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                 }
3036             }
3037         } finally {
3038             Binder.restoreCallingIdentity(callingId);
3039         }
3040     }
3041
3042     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043     @Override
3044     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046         synchronized (this) {
3047             if (listener != null) {
3048                 mTaskStackListeners.register(listener);
3049             }
3050         }
3051     }
3052
3053     @Override
3054     public void notifyActivityDrawn(IBinder token) {
3055         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056         synchronized (this) {
3057             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058             if (r != null) {
3059                 r.task.stack.notifyActivityDrawnLocked(r);
3060             }
3061         }
3062     }
3063
3064     final void applyUpdateLockStateLocked(ActivityRecord r) {
3065         // Modifications to the UpdateLock state are done on our handler, outside
3066         // the activity manager's locks.  The new state is determined based on the
3067         // state *now* of the relevant activity record.  The object is passed to
3068         // the handler solely for logging detail, not to be consulted/modified.
3069         final boolean nextState = r != null && r.immersive;
3070         mHandler.sendMessage(
3071                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072     }
3073
3074     final void applyUpdateVrModeLocked(ActivityRecord r) {
3075         mHandler.sendMessage(
3076                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077     }
3078
3079     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080         mHandler.sendMessage(
3081                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082     }
3083
3084     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3085         Message msg = Message.obtain();
3086         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3087         msg.obj = r.task.askedCompatMode ? null : r;
3088         mUiHandler.sendMessage(msg);
3089     }
3090
3091     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3092             String what, Object obj, ProcessRecord srcApp) {
3093         app.lastActivityTime = now;
3094
3095         if (app.activities.size() > 0) {
3096             // Don't want to touch dependent processes that are hosting activities.
3097             return index;
3098         }
3099
3100         int lrui = mLruProcesses.lastIndexOf(app);
3101         if (lrui < 0) {
3102             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3103                     + what + " " + obj + " from " + srcApp);
3104             return index;
3105         }
3106
3107         if (lrui >= index) {
3108             // Don't want to cause this to move dependent processes *back* in the
3109             // list as if they were less frequently used.
3110             return index;
3111         }
3112
3113         if (lrui >= mLruProcessActivityStart) {
3114             // Don't want to touch dependent processes that are hosting activities.
3115             return index;
3116         }
3117
3118         mLruProcesses.remove(lrui);
3119         if (index > 0) {
3120             index--;
3121         }
3122         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3123                 + " in LRU list: " + app);
3124         mLruProcesses.add(index, app);
3125         return index;
3126     }
3127
3128     static void killProcessGroup(int uid, int pid) {
3129         if (sKillHandler != null) {
3130             sKillHandler.sendMessage(
3131                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3132         } else {
3133             Slog.w(TAG, "Asked to kill process group before system bringup!");
3134             Process.killProcessGroup(uid, pid);
3135         }
3136     }
3137
3138     final void removeLruProcessLocked(ProcessRecord app) {
3139         int lrui = mLruProcesses.lastIndexOf(app);
3140         if (lrui >= 0) {
3141             if (!app.killed) {
3142                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3143                 Process.killProcessQuiet(app.pid);
3144                 killProcessGroup(app.uid, app.pid);
3145             }
3146             if (lrui <= mLruProcessActivityStart) {
3147                 mLruProcessActivityStart--;
3148             }
3149             if (lrui <= mLruProcessServiceStart) {
3150                 mLruProcessServiceStart--;
3151             }
3152             mLruProcesses.remove(lrui);
3153         }
3154     }
3155
3156     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3157             ProcessRecord client) {
3158         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3159                 || app.treatLikeActivity;
3160         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3161         if (!activityChange && hasActivity) {
3162             // The process has activities, so we are only allowing activity-based adjustments
3163             // to move it.  It should be kept in the front of the list with other
3164             // processes that have activities, and we don't want those to change their
3165             // order except due to activity operations.
3166             return;
3167         }
3168
3169         mLruSeq++;
3170         final long now = SystemClock.uptimeMillis();
3171         app.lastActivityTime = now;
3172
3173         // First a quick reject: if the app is already at the position we will
3174         // put it, then there is nothing to do.
3175         if (hasActivity) {
3176             final int N = mLruProcesses.size();
3177             if (N > 0 && mLruProcesses.get(N-1) == app) {
3178                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3179                 return;
3180             }
3181         } else {
3182             if (mLruProcessServiceStart > 0
3183                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3184                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3185                 return;
3186             }
3187         }
3188
3189         int lrui = mLruProcesses.lastIndexOf(app);
3190
3191         if (app.persistent && lrui >= 0) {
3192             // We don't care about the position of persistent processes, as long as
3193             // they are in the list.
3194             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3195             return;
3196         }
3197
3198         /* In progress: compute new position first, so we can avoid doing work
3199            if the process is not actually going to move.  Not yet working.
3200         int addIndex;
3201         int nextIndex;
3202         boolean inActivity = false, inService = false;
3203         if (hasActivity) {
3204             // Process has activities, put it at the very tipsy-top.
3205             addIndex = mLruProcesses.size();
3206             nextIndex = mLruProcessServiceStart;
3207             inActivity = true;
3208         } else if (hasService) {
3209             // Process has services, put it at the top of the service list.
3210             addIndex = mLruProcessActivityStart;
3211             nextIndex = mLruProcessServiceStart;
3212             inActivity = true;
3213             inService = true;
3214         } else  {
3215             // Process not otherwise of interest, it goes to the top of the non-service area.
3216             addIndex = mLruProcessServiceStart;
3217             if (client != null) {
3218                 int clientIndex = mLruProcesses.lastIndexOf(client);
3219                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3220                         + app);
3221                 if (clientIndex >= 0 && addIndex > clientIndex) {
3222                     addIndex = clientIndex;
3223                 }
3224             }
3225             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3226         }
3227
3228         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3229                 + mLruProcessActivityStart + "): " + app);
3230         */
3231
3232         if (lrui >= 0) {
3233             if (lrui < mLruProcessActivityStart) {
3234                 mLruProcessActivityStart--;
3235             }
3236             if (lrui < mLruProcessServiceStart) {
3237                 mLruProcessServiceStart--;
3238             }
3239             /*
3240             if (addIndex > lrui) {
3241                 addIndex--;
3242             }
3243             if (nextIndex > lrui) {
3244                 nextIndex--;
3245             }
3246             */
3247             mLruProcesses.remove(lrui);
3248         }
3249
3250         /*
3251         mLruProcesses.add(addIndex, app);
3252         if (inActivity) {
3253             mLruProcessActivityStart++;
3254         }
3255         if (inService) {
3256             mLruProcessActivityStart++;
3257         }
3258         */
3259
3260         int nextIndex;
3261         if (hasActivity) {
3262             final int N = mLruProcesses.size();
3263             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3264                 // Process doesn't have activities, but has clients with
3265                 // activities...  move it up, but one below the top (the top
3266                 // should always have a real activity).
3267                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3268                         "Adding to second-top of LRU activity list: " + app);
3269                 mLruProcesses.add(N - 1, app);
3270                 // To keep it from spamming the LRU list (by making a bunch of clients),
3271                 // we will push down any other entries owned by the app.
3272                 final int uid = app.info.uid;
3273                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3274                     ProcessRecord subProc = mLruProcesses.get(i);
3275                     if (subProc.info.uid == uid) {
3276                         // We want to push this one down the list.  If the process after
3277                         // it is for the same uid, however, don't do so, because we don't
3278                         // want them internally to be re-ordered.
3279                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3280                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3281                                     "Pushing uid " + uid + " swapping at " + i + ": "
3282                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3283                             ProcessRecord tmp = mLruProcesses.get(i);
3284                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3285                             mLruProcesses.set(i - 1, tmp);
3286                             i--;
3287                         }
3288                     } else {
3289                         // A gap, we can stop here.
3290                         break;
3291                     }
3292                 }
3293             } else {
3294                 // Process has activities, put it at the very tipsy-top.
3295                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3296                 mLruProcesses.add(app);
3297             }
3298             nextIndex = mLruProcessServiceStart;
3299         } else if (hasService) {
3300             // Process has services, put it at the top of the service list.
3301             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3302             mLruProcesses.add(mLruProcessActivityStart, app);
3303             nextIndex = mLruProcessServiceStart;
3304             mLruProcessActivityStart++;
3305         } else  {
3306             // Process not otherwise of interest, it goes to the top of the non-service area.
3307             int index = mLruProcessServiceStart;
3308             if (client != null) {
3309                 // If there is a client, don't allow the process to be moved up higher
3310                 // in the list than that client.
3311                 int clientIndex = mLruProcesses.lastIndexOf(client);
3312                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3313                         + " when updating " + app);
3314                 if (clientIndex <= lrui) {
3315                     // Don't allow the client index restriction to push it down farther in the
3316                     // list than it already is.
3317                     clientIndex = lrui;
3318                 }
3319                 if (clientIndex >= 0 && index > clientIndex) {
3320                     index = clientIndex;
3321                 }
3322             }
3323             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3324             mLruProcesses.add(index, app);
3325             nextIndex = index-1;
3326             mLruProcessActivityStart++;
3327             mLruProcessServiceStart++;
3328         }
3329
3330         // If the app is currently using a content provider or service,
3331         // bump those processes as well.
3332         for (int j=app.connections.size()-1; j>=0; j--) {
3333             ConnectionRecord cr = app.connections.valueAt(j);
3334             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3335                     && cr.binding.service.app != null
3336                     && cr.binding.service.app.lruSeq != mLruSeq
3337                     && !cr.binding.service.app.persistent) {
3338                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3339                         "service connection", cr, app);
3340             }
3341         }
3342         for (int j=app.conProviders.size()-1; j>=0; j--) {
3343             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3344             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3345                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3346                         "provider reference", cpr, app);
3347             }
3348         }
3349     }
3350
3351     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3352         if (uid == Process.SYSTEM_UID) {
3353             // The system gets to run in any process.  If there are multiple
3354             // processes with the same uid, just pick the first (this
3355             // should never happen).
3356             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3357             if (procs == null) return null;
3358             final int procCount = procs.size();
3359             for (int i = 0; i < procCount; i++) {
3360                 final int procUid = procs.keyAt(i);
3361                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3362                     // Don't use an app process or different user process for system component.
3363                     continue;
3364                 }
3365                 return procs.valueAt(i);
3366             }
3367         }
3368         ProcessRecord proc = mProcessNames.get(processName, uid);
3369         if (false && proc != null && !keepIfLarge
3370                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3371                 && proc.lastCachedPss >= 4000) {
3372             // Turn this condition on to cause killing to happen regularly, for testing.
3373             if (proc.baseProcessTracker != null) {
3374                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3375             }
3376             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3377         } else if (proc != null && !keepIfLarge
3378                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3379                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3380             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3381             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3382                 if (proc.baseProcessTracker != null) {
3383                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3384                 }
3385                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3386             }
3387         }
3388         return proc;
3389     }
3390
3391     void notifyPackageUse(String packageName, int reason) {
3392         IPackageManager pm = AppGlobals.getPackageManager();
3393         try {
3394             pm.notifyPackageUse(packageName, reason);
3395         } catch (RemoteException e) {
3396         }
3397     }
3398
3399     boolean isNextTransitionForward() {
3400         int transit = mWindowManager.getPendingAppTransition();
3401         return transit == TRANSIT_ACTIVITY_OPEN
3402                 || transit == TRANSIT_TASK_OPEN
3403                 || transit == TRANSIT_TASK_TO_FRONT;
3404     }
3405
3406     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3407             String processName, String abiOverride, int uid, Runnable crashHandler) {
3408         synchronized(this) {
3409             ApplicationInfo info = new ApplicationInfo();
3410             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3411             // For isolated processes, the former contains the parent's uid and the latter the
3412             // actual uid of the isolated process.
3413             // In the special case introduced by this method (which is, starting an isolated
3414             // process directly from the SystemServer without an actual parent app process) the
3415             // closest thing to a parent's uid is SYSTEM_UID.
3416             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3417             // the |isolated| logic in the ProcessRecord constructor.
3418             info.uid = Process.SYSTEM_UID;
3419             info.processName = processName;
3420             info.className = entryPoint;
3421             info.packageName = "android";
3422             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3423                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3424                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3425                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3426                     crashHandler);
3427             return proc != null ? proc.pid : 0;
3428         }
3429     }
3430
3431     final ProcessRecord startProcessLocked(String processName,
3432             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3433             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3434             boolean isolated, boolean keepIfLarge) {
3435         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3436                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3437                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3438                 null /* crashHandler */);
3439     }
3440
3441     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3442             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3443             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3444             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3445         long startTime = SystemClock.elapsedRealtime();
3446         ProcessRecord app;
3447         if (!isolated) {
3448             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3449             checkTime(startTime, "startProcess: after getProcessRecord");
3450
3451             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3452                 // If we are in the background, then check to see if this process
3453                 // is bad.  If so, we will just silently fail.
3454                 if (mAppErrors.isBadProcessLocked(info)) {
3455                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3456                             + "/" + info.processName);
3457                     return null;
3458                 }
3459             } else {
3460                 // When the user is explicitly starting a process, then clear its
3461                 // crash count so that we won't make it bad until they see at
3462                 // least one crash dialog again, and make the process good again
3463                 // if it had been bad.
3464                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3465                         + "/" + info.processName);
3466                 mAppErrors.resetProcessCrashTimeLocked(info);
3467                 if (mAppErrors.isBadProcessLocked(info)) {
3468                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3469                             UserHandle.getUserId(info.uid), info.uid,
3470                             info.processName);
3471                     mAppErrors.clearBadProcessLocked(info);
3472                     if (app != null) {
3473                         app.bad = false;
3474                     }
3475                 }
3476             }
3477         } else {
3478             // If this is an isolated process, it can't re-use an existing process.
3479             app = null;
3480         }
3481
3482         // app launch boost for big.little configurations
3483         // use cpusets to migrate freshly launched tasks to big cores
3484         synchronized(ActivityManagerService.this) {
3485             nativeMigrateToBoost();
3486             mIsBoosted = true;
3487             mBoostStartTime = SystemClock.uptimeMillis();
3488             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3489             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3490         }
3491
3492         // We don't have to do anything more if:
3493         // (1) There is an existing application record; and
3494         // (2) The caller doesn't think it is dead, OR there is no thread
3495         //     object attached to it so we know it couldn't have crashed; and
3496         // (3) There is a pid assigned to it, so it is either starting or
3497         //     already running.
3498         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3499                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3500                 + " thread=" + (app != null ? app.thread : null)
3501                 + " pid=" + (app != null ? app.pid : -1));
3502         if (app != null && app.pid > 0) {
3503             if (!knownToBeDead || app.thread == null) {
3504                 // We already have the app running, or are waiting for it to
3505                 // come up (we have a pid but not yet its thread), so keep it.
3506                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3507                 // If this is a new package in the process, add the package to the list
3508                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509                 checkTime(startTime, "startProcess: done, added package to proc");
3510                 return app;
3511             }
3512
3513             // An application record is attached to a previous process,
3514             // clean it up now.
3515             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3516             checkTime(startTime, "startProcess: bad proc running, killing");
3517             killProcessGroup(app.uid, app.pid);
3518             handleAppDiedLocked(app, true, true);
3519             checkTime(startTime, "startProcess: done killing old proc");
3520         }
3521
3522         String hostingNameStr = hostingName != null
3523                 ? hostingName.flattenToShortString() : null;
3524
3525         if (app == null) {
3526             checkTime(startTime, "startProcess: creating new process record");
3527             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3528             if (app == null) {
3529                 Slog.w(TAG, "Failed making new process record for "
3530                         + processName + "/" + info.uid + " isolated=" + isolated);
3531                 return null;
3532             }
3533             app.crashHandler = crashHandler;
3534             checkTime(startTime, "startProcess: done creating new process record");
3535         } else {
3536             // If this is a new package in the process, add the package to the list
3537             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3538             checkTime(startTime, "startProcess: added package to existing proc");
3539         }
3540
3541         // If the system is not ready yet, then hold off on starting this
3542         // process until it is.
3543         if (!mProcessesReady
3544                 && !isAllowedWhileBooting(info)
3545                 && !allowWhileBooting) {
3546             if (!mProcessesOnHold.contains(app)) {
3547                 mProcessesOnHold.add(app);
3548             }
3549             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3550                     "System not ready, putting on hold: " + app);
3551             checkTime(startTime, "startProcess: returning with proc on hold");
3552             return app;
3553         }
3554
3555         checkTime(startTime, "startProcess: stepping in to startProcess");
3556         startProcessLocked(
3557                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3558         checkTime(startTime, "startProcess: done starting proc!");
3559         return (app.pid != 0) ? app : null;
3560     }
3561
3562     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3563         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3564     }
3565
3566     private final void startProcessLocked(ProcessRecord app,
3567             String hostingType, String hostingNameStr) {
3568         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3569                 null /* entryPoint */, null /* entryPointArgs */);
3570     }
3571
3572     private final void startProcessLocked(ProcessRecord app, String hostingType,
3573             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3574         long startTime = SystemClock.elapsedRealtime();
3575         if (app.pid > 0 && app.pid != MY_PID) {
3576             checkTime(startTime, "startProcess: removing from pids map");
3577             synchronized (mPidsSelfLocked) {
3578                 mPidsSelfLocked.remove(app.pid);
3579                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3580             }
3581             checkTime(startTime, "startProcess: done removing from pids map");
3582             app.setPid(0);
3583         }
3584
3585         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3586                 "startProcessLocked removing on hold: " + app);
3587         mProcessesOnHold.remove(app);
3588
3589         checkTime(startTime, "startProcess: starting to update cpu stats");
3590         updateCpuStats();
3591         checkTime(startTime, "startProcess: done updating cpu stats");
3592
3593         try {
3594             try {
3595                 final int userId = UserHandle.getUserId(app.uid);
3596                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3597             } catch (RemoteException e) {
3598                 throw e.rethrowAsRuntimeException();
3599             }
3600
3601             int uid = app.uid;
3602             int[] gids = null;
3603             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3604             if (!app.isolated) {
3605                 int[] permGids = null;
3606                 try {
3607                     checkTime(startTime, "startProcess: getting gids from package manager");
3608                     final IPackageManager pm = AppGlobals.getPackageManager();
3609                     permGids = pm.getPackageGids(app.info.packageName,
3610                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3611                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3612                             MountServiceInternal.class);
3613                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3614                             app.info.packageName);
3615                 } catch (RemoteException e) {
3616                     throw e.rethrowAsRuntimeException();
3617                 }
3618
3619                 /*
3620                  * Add shared application and profile GIDs so applications can share some
3621                  * resources like shared libraries and access user-wide resources
3622                  */
3623                 if (ArrayUtils.isEmpty(permGids)) {
3624                     gids = new int[2];
3625                 } else {
3626                     gids = new int[permGids.length + 2];
3627                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3628                 }
3629                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3630                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3631             }
3632             checkTime(startTime, "startProcess: building args");
3633             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3634                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3635                         && mTopComponent != null
3636                         && app.processName.equals(mTopComponent.getPackageName())) {
3637                     uid = 0;
3638                 }
3639                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3640                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3641                     uid = 0;
3642                 }
3643             }
3644             int debugFlags = 0;
3645             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3646                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3647                 // Also turn on CheckJNI for debuggable apps. It's quite
3648                 // awkward to turn on otherwise.
3649                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3650             }
3651             // Run the app in safe mode if its manifest requests so or the
3652             // system is booted in safe mode.
3653             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3654                 mSafeMode == true) {
3655                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3656             }
3657             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3658                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3659             }
3660             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3661             if ("true".equals(genDebugInfoProperty)) {
3662                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3663             }
3664             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3665                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3666             }
3667             if ("1".equals(SystemProperties.get("debug.assert"))) {
3668                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3669             }
3670             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3671                 // Enable all debug flags required by the native debugger.
3672                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3673                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3674                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3675                 mNativeDebuggingApp = null;
3676             }
3677
3678             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3679             if (requiredAbi == null) {
3680                 requiredAbi = Build.SUPPORTED_ABIS[0];
3681             }
3682
3683             String instructionSet = null;
3684             if (app.info.primaryCpuAbi != null) {
3685                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3686             }
3687
3688             app.gids = gids;
3689             app.requiredAbi = requiredAbi;
3690             app.instructionSet = instructionSet;
3691
3692             // Start the process.  It will either succeed and return a result containing
3693             // the PID of the new process, or else throw a RuntimeException.
3694             boolean isActivityProcess = (entryPoint == null);
3695             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3696             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3697                     app.processName);
3698             checkTime(startTime, "startProcess: asking zygote to start proc");
3699             Process.ProcessStartResult startResult = Process.start(entryPoint,
3700                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3701                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3702                     app.info.dataDir, entryPointArgs);
3703             checkTime(startTime, "startProcess: returned from zygote!");
3704             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3705
3706             if (app.isolated) {
3707                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3708             }
3709             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3710             checkTime(startTime, "startProcess: done updating battery stats");
3711
3712             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3713                     UserHandle.getUserId(uid), startResult.pid, uid,
3714                     app.processName, hostingType,
3715                     hostingNameStr != null ? hostingNameStr : "");
3716
3717             try {
3718                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3719                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3720             } catch (RemoteException ex) {
3721                 // Ignore
3722             }
3723
3724             if (app.persistent) {
3725                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3726             }
3727
3728             checkTime(startTime, "startProcess: building log message");
3729             StringBuilder buf = mStringBuilder;
3730             buf.setLength(0);
3731             buf.append("Start proc ");
3732             buf.append(startResult.pid);
3733             buf.append(':');
3734             buf.append(app.processName);
3735             buf.append('/');
3736             UserHandle.formatUid(buf, uid);
3737             if (!isActivityProcess) {
3738                 buf.append(" [");
3739                 buf.append(entryPoint);
3740                 buf.append("]");
3741             }
3742             buf.append(" for ");
3743             buf.append(hostingType);
3744             if (hostingNameStr != null) {
3745                 buf.append(" ");
3746                 buf.append(hostingNameStr);
3747             }
3748             Slog.i(TAG, buf.toString());
3749             app.setPid(startResult.pid);
3750             app.usingWrapper = startResult.usingWrapper;
3751             app.removed = false;
3752             app.killed = false;
3753             app.killedByAm = false;
3754             checkTime(startTime, "startProcess: starting to update pids map");
3755             synchronized (mPidsSelfLocked) {
3756                 this.mPidsSelfLocked.put(startResult.pid, app);
3757                 if (isActivityProcess) {
3758                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3759                     msg.obj = app;
3760                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3761                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3762                 }
3763             }
3764             checkTime(startTime, "startProcess: done updating pids map");
3765         } catch (RuntimeException e) {
3766             Slog.e(TAG, "Failure starting process " + app.processName, e);
3767
3768             // Something went very wrong while trying to start this process; one
3769             // common case is when the package is frozen due to an active
3770             // upgrade. To recover, clean up any active bookkeeping related to
3771             // starting this process. (We already invoked this method once when
3772             // the package was initially frozen through KILL_APPLICATION_MSG, so
3773             // it doesn't hurt to use it again.)
3774             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3775                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3776         }
3777     }
3778
3779     void updateUsageStats(ActivityRecord component, boolean resumed) {
3780         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3781                 "updateUsageStats: comp=" + component + "res=" + resumed);
3782         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3783         if (resumed) {
3784             if (mUsageStatsService != null) {
3785                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3786                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3787             }
3788             synchronized (stats) {
3789                 stats.noteActivityResumedLocked(component.app.uid);
3790             }
3791         } else {
3792             if (mUsageStatsService != null) {
3793                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3794                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3795             }
3796             synchronized (stats) {
3797                 stats.noteActivityPausedLocked(component.app.uid);
3798             }
3799         }
3800     }
3801
3802     Intent getHomeIntent() {
3803         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3804         intent.setComponent(mTopComponent);
3805         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3806         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3807             intent.addCategory(Intent.CATEGORY_HOME);
3808         }
3809         return intent;
3810     }
3811
3812     boolean startHomeActivityLocked(int userId, String reason) {
3813         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3814                 && mTopAction == null) {
3815             // We are running in factory test mode, but unable to find
3816             // the factory test app, so just sit around displaying the
3817             // error message and don't try to start anything.
3818             return false;
3819         }
3820         Intent intent = getHomeIntent();
3821         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3822         if (aInfo != null) {
3823             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3824             // Don't do this if the home app is currently being
3825             // instrumented.
3826             aInfo = new ActivityInfo(aInfo);
3827             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3828             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3829                     aInfo.applicationInfo.uid, true);
3830             if (app == null || app.instrumentationClass == null) {
3831                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3832                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3833             }
3834         } else {
3835             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3836         }
3837
3838         return true;
3839     }
3840
3841     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3842         ActivityInfo ai = null;
3843         ComponentName comp = intent.getComponent();
3844         try {
3845             if (comp != null) {
3846                 // Factory test.
3847                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3848             } else {
3849                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3850                         intent,
3851                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3852                         flags, userId);
3853
3854                 if (info != null) {
3855                     ai = info.activityInfo;
3856                 }
3857             }
3858         } catch (RemoteException e) {
3859             // ignore
3860         }
3861
3862         return ai;
3863     }
3864
3865     /**
3866      * Starts the "new version setup screen" if appropriate.
3867      */
3868     void startSetupActivityLocked() {
3869         // Only do this once per boot.
3870         if (mCheckedForSetup) {
3871             return;
3872         }
3873
3874         // We will show this screen if the current one is a different
3875         // version than the last one shown, and we are not running in
3876         // low-level factory test mode.
3877         final ContentResolver resolver = mContext.getContentResolver();
3878         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3879                 Settings.Global.getInt(resolver,
3880                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3881             mCheckedForSetup = true;
3882
3883             // See if we should be showing the platform update setup UI.
3884             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3885             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3886                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3887             if (!ris.isEmpty()) {
3888                 final ResolveInfo ri = ris.get(0);
3889                 String vers = ri.activityInfo.metaData != null
3890                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3891                         : null;
3892                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3893                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3894                             Intent.METADATA_SETUP_VERSION);
3895                 }
3896                 String lastVers = Settings.Secure.getString(
3897                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3898                 if (vers != null && !vers.equals(lastVers)) {
3899                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3900                     intent.setComponent(new ComponentName(
3901                             ri.activityInfo.packageName, ri.activityInfo.name));
3902                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3903                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3904                             null, 0, 0, 0, null, false, false, null, null, null);
3905                 }
3906             }
3907         }
3908     }
3909
3910     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3911         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3912     }
3913
3914     void enforceNotIsolatedCaller(String caller) {
3915         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3916             throw new SecurityException("Isolated process not allowed to call " + caller);
3917         }
3918     }
3919
3920     void enforceShellRestriction(String restriction, int userHandle) {
3921         if (Binder.getCallingUid() == Process.SHELL_UID) {
3922             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3923                 throw new SecurityException("Shell does not have permission to access user "
3924                         + userHandle);
3925             }
3926         }
3927     }
3928
3929     @Override
3930     public int getFrontActivityScreenCompatMode() {
3931         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3932         synchronized (this) {
3933             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3934         }
3935     }
3936
3937     @Override
3938     public void setFrontActivityScreenCompatMode(int mode) {
3939         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3940                 "setFrontActivityScreenCompatMode");
3941         synchronized (this) {
3942             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3943         }
3944     }
3945
3946     @Override
3947     public int getPackageScreenCompatMode(String packageName) {
3948         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3949         synchronized (this) {
3950             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3951         }
3952     }
3953
3954     @Override
3955     public void setPackageScreenCompatMode(String packageName, int mode) {
3956         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3957                 "setPackageScreenCompatMode");
3958         synchronized (this) {
3959             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3960         }
3961     }
3962
3963     @Override
3964     public boolean getPackageAskScreenCompat(String packageName) {
3965         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3966         synchronized (this) {
3967             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3968         }
3969     }
3970
3971     @Override
3972     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3973         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3974                 "setPackageAskScreenCompat");
3975         synchronized (this) {
3976             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3977         }
3978     }
3979
3980     private boolean hasUsageStatsPermission(String callingPackage) {
3981         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3982                 Binder.getCallingUid(), callingPackage);
3983         if (mode == AppOpsManager.MODE_DEFAULT) {
3984             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3985                     == PackageManager.PERMISSION_GRANTED;
3986         }
3987         return mode == AppOpsManager.MODE_ALLOWED;
3988     }
3989
3990     @Override
3991     public int getPackageProcessState(String packageName, String callingPackage) {
3992         if (!hasUsageStatsPermission(callingPackage)) {
3993             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3994                     "getPackageProcessState");
3995         }
3996
3997         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3998         synchronized (this) {
3999             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4000                 final ProcessRecord proc = mLruProcesses.get(i);
4001                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4002                         || procState > proc.setProcState) {
4003                     boolean found = false;
4004                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4005                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4006                             procState = proc.setProcState;
4007                             found = true;
4008                         }
4009                     }
4010                     if (proc.pkgDeps != null && !found) {
4011                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4012                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4013                                 procState = proc.setProcState;
4014                                 break;
4015                             }
4016                         }
4017                     }
4018                 }
4019             }
4020         }
4021         return procState;
4022     }
4023
4024     @Override
4025     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4026         synchronized (this) {
4027             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4028             if (app == null) {
4029                 return false;
4030             }
4031             if (app.trimMemoryLevel < level && app.thread != null &&
4032                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4033                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4034                 try {
4035                     app.thread.scheduleTrimMemory(level);
4036                     app.trimMemoryLevel = level;
4037                     return true;
4038                 } catch (RemoteException e) {
4039                     // Fallthrough to failure case.
4040                 }
4041             }
4042         }
4043         return false;
4044     }
4045
4046     private void dispatchProcessesChanged() {
4047         int N;
4048         synchronized (this) {
4049             N = mPendingProcessChanges.size();
4050             if (mActiveProcessChanges.length < N) {
4051                 mActiveProcessChanges = new ProcessChangeItem[N];
4052             }
4053             mPendingProcessChanges.toArray(mActiveProcessChanges);
4054             mPendingProcessChanges.clear();
4055             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4056                     "*** Delivering " + N + " process changes");
4057         }
4058
4059         int i = mProcessObservers.beginBroadcast();
4060         while (i > 0) {
4061             i--;
4062             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4063             if (observer != null) {
4064                 try {
4065                     for (int j=0; j<N; j++) {
4066                         ProcessChangeItem item = mActiveProcessChanges[j];
4067                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4068                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4069                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4070                                     + item.uid + ": " + item.foregroundActivities);
4071                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4072                                     item.foregroundActivities);
4073                         }
4074                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4075                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4076                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4077                                     + ": " + item.processState);
4078                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4079                         }
4080                     }
4081                 } catch (RemoteException e) {
4082                 }
4083             }
4084         }
4085         mProcessObservers.finishBroadcast();
4086
4087         synchronized (this) {
4088             for (int j=0; j<N; j++) {
4089                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4090             }
4091         }
4092     }
4093
4094     private void dispatchProcessDied(int pid, int uid) {
4095         int i = mProcessObservers.beginBroadcast();
4096         while (i > 0) {
4097             i--;
4098             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4099             if (observer != null) {
4100                 try {
4101                     observer.onProcessDied(pid, uid);
4102                 } catch (RemoteException e) {
4103                 }
4104             }
4105         }
4106         mProcessObservers.finishBroadcast();
4107     }
4108
4109     private void dispatchUidsChanged() {
4110         int N;
4111         synchronized (this) {
4112             N = mPendingUidChanges.size();
4113             if (mActiveUidChanges.length < N) {
4114                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4115             }
4116             for (int i=0; i<N; i++) {
4117                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4118                 mActiveUidChanges[i] = change;
4119                 if (change.uidRecord != null) {
4120                     change.uidRecord.pendingChange = null;
4121                     change.uidRecord = null;
4122                 }
4123             }
4124             mPendingUidChanges.clear();
4125             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4126                     "*** Delivering " + N + " uid changes");
4127         }
4128
4129         if (mLocalPowerManager != null) {
4130             for (int j=0; j<N; j++) {
4131                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4132                 if (item.change == UidRecord.CHANGE_GONE
4133                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4134                     mLocalPowerManager.uidGone(item.uid);
4135                 } else {
4136                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4137                 }
4138             }
4139         }
4140
4141         int i = mUidObservers.beginBroadcast();
4142         while (i > 0) {
4143             i--;
4144             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4145             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4146             if (observer != null) {
4147                 try {
4148                     for (int j=0; j<N; j++) {
4149                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4150                         final int change = item.change;
4151                         UidRecord validateUid = null;
4152                         if (VALIDATE_UID_STATES && i == 0) {
4153                             validateUid = mValidateUids.get(item.uid);
4154                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4155                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4156                                 validateUid = new UidRecord(item.uid);
4157                                 mValidateUids.put(item.uid, validateUid);
4158                             }
4159                         }
4160                         if (change == UidRecord.CHANGE_IDLE
4161                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4162                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4163                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4164                                         "UID idle uid=" + item.uid);
4165                                 observer.onUidIdle(item.uid);
4166                             }
4167                             if (VALIDATE_UID_STATES && i == 0) {
4168                                 if (validateUid != null) {
4169                                     validateUid.idle = true;
4170                                 }
4171                             }
4172                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4173                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4174                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                                         "UID active uid=" + item.uid);
4176                                 observer.onUidActive(item.uid);
4177                             }
4178                             if (VALIDATE_UID_STATES && i == 0) {
4179                                 validateUid.idle = false;
4180                             }
4181                         }
4182                         if (change == UidRecord.CHANGE_GONE
4183                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4184                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4185                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186                                         "UID gone uid=" + item.uid);
4187                                 observer.onUidGone(item.uid);
4188                             }
4189                             if (VALIDATE_UID_STATES && i == 0) {
4190                                 if (validateUid != null) {
4191                                     mValidateUids.remove(item.uid);
4192                                 }
4193                             }
4194                         } else {
4195                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4196                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                         "UID CHANGED uid=" + item.uid
4198                                                 + ": " + item.processState);
4199                                 observer.onUidStateChanged(item.uid, item.processState);
4200                             }
4201                             if (VALIDATE_UID_STATES && i == 0) {
4202                                 validateUid.curProcState = validateUid.setProcState
4203                                         = item.processState;
4204                             }
4205                         }
4206                     }
4207                 } catch (RemoteException e) {
4208                 }
4209             }
4210         }
4211         mUidObservers.finishBroadcast();
4212
4213         synchronized (this) {
4214             for (int j=0; j<N; j++) {
4215                 mAvailUidChanges.add(mActiveUidChanges[j]);
4216             }
4217         }
4218     }
4219
4220     @Override
4221     public final int startActivity(IApplicationThread caller, String callingPackage,
4222             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4224         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4225                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4226                 UserHandle.getCallingUserId());
4227     }
4228
4229     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4230         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4231         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4232                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4233                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4234
4235         // TODO: Switch to user app stacks here.
4236         String mimeType = intent.getType();
4237         final Uri data = intent.getData();
4238         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4239             mimeType = getProviderMimeType(data, userId);
4240         }
4241         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4242
4243         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4244         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4245                 null, 0, 0, null, null, null, null, false, userId, container, null);
4246     }
4247
4248     @Override
4249     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4250             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4251             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4252         enforceNotIsolatedCaller("startActivity");
4253         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4254                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4255         // TODO: Switch to user app stacks here.
4256         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4257                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4258                 profilerInfo, null, null, bOptions, false, userId, null, null);
4259     }
4260
4261     @Override
4262     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4263             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4265             int userId) {
4266
4267         // This is very dangerous -- it allows you to perform a start activity (including
4268         // permission grants) as any app that may launch one of your own activities.  So
4269         // we will only allow this to be done from activities that are part of the core framework,
4270         // and then only when they are running as the system.
4271         final ActivityRecord sourceRecord;
4272         final int targetUid;
4273         final String targetPackage;
4274         synchronized (this) {
4275             if (resultTo == null) {
4276                 throw new SecurityException("Must be called from an activity");
4277             }
4278             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4279             if (sourceRecord == null) {
4280                 throw new SecurityException("Called with bad activity token: " + resultTo);
4281             }
4282             if (!sourceRecord.info.packageName.equals("android")) {
4283                 throw new SecurityException(
4284                         "Must be called from an activity that is declared in the android package");
4285             }
4286             if (sourceRecord.app == null) {
4287                 throw new SecurityException("Called without a process attached to activity");
4288             }
4289             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4290                 // This is still okay, as long as this activity is running under the
4291                 // uid of the original calling activity.
4292                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4293                     throw new SecurityException(
4294                             "Calling activity in uid " + sourceRecord.app.uid
4295                                     + " must be system uid or original calling uid "
4296                                     + sourceRecord.launchedFromUid);
4297                 }
4298             }
4299             if (ignoreTargetSecurity) {
4300                 if (intent.getComponent() == null) {
4301                     throw new SecurityException(
4302                             "Component must be specified with ignoreTargetSecurity");
4303                 }
4304                 if (intent.getSelector() != null) {
4305                     throw new SecurityException(
4306                             "Selector not allowed with ignoreTargetSecurity");
4307                 }
4308             }
4309             targetUid = sourceRecord.launchedFromUid;
4310             targetPackage = sourceRecord.launchedFromPackage;
4311         }
4312
4313         if (userId == UserHandle.USER_NULL) {
4314             userId = UserHandle.getUserId(sourceRecord.app.uid);
4315         }
4316
4317         // TODO: Switch to user app stacks here.
4318         try {
4319             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4320                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4321                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4322             return ret;
4323         } catch (SecurityException e) {
4324             // XXX need to figure out how to propagate to original app.
4325             // A SecurityException here is generally actually a fault of the original
4326             // calling activity (such as a fairly granting permissions), so propagate it
4327             // back to them.
4328             /*
4329             StringBuilder msg = new StringBuilder();
4330             msg.append("While launching");
4331             msg.append(intent.toString());
4332             msg.append(": ");
4333             msg.append(e.getMessage());
4334             */
4335             throw e;
4336         }
4337     }
4338
4339     @Override
4340     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4341             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4342             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4343         enforceNotIsolatedCaller("startActivityAndWait");
4344         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4345                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4346         WaitResult res = new WaitResult();
4347         // TODO: Switch to user app stacks here.
4348         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4349                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4350                 bOptions, false, userId, null, null);
4351         return res;
4352     }
4353
4354     @Override
4355     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4356             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4357             int startFlags, Configuration config, Bundle bOptions, int userId) {
4358         enforceNotIsolatedCaller("startActivityWithConfig");
4359         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4361         // TODO: Switch to user app stacks here.
4362         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4363                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4364                 null, null, config, bOptions, false, userId, null, null);
4365         return ret;
4366     }
4367
4368     @Override
4369     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4370             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4371             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4372             throws TransactionTooLargeException {
4373         enforceNotIsolatedCaller("startActivityIntentSender");
4374         // Refuse possible leaked file descriptors
4375         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4376             throw new IllegalArgumentException("File descriptors passed in Intent");
4377         }
4378
4379         IIntentSender sender = intent.getTarget();
4380         if (!(sender instanceof PendingIntentRecord)) {
4381             throw new IllegalArgumentException("Bad PendingIntent object");
4382         }
4383
4384         PendingIntentRecord pir = (PendingIntentRecord)sender;
4385
4386         synchronized (this) {
4387             // If this is coming from the currently resumed activity, it is
4388             // effectively saying that app switches are allowed at this point.
4389             final ActivityStack stack = getFocusedStack();
4390             if (stack.mResumedActivity != null &&
4391                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4392                 mAppSwitchesAllowedTime = 0;
4393             }
4394         }
4395         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4396                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4397         return ret;
4398     }
4399
4400     @Override
4401     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4402             Intent intent, String resolvedType, IVoiceInteractionSession session,
4403             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4404             Bundle bOptions, int userId) {
4405         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4406                 != PackageManager.PERMISSION_GRANTED) {
4407             String msg = "Permission Denial: startVoiceActivity() from pid="
4408                     + Binder.getCallingPid()
4409                     + ", uid=" + Binder.getCallingUid()
4410                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4411             Slog.w(TAG, msg);
4412             throw new SecurityException(msg);
4413         }
4414         if (session == null || interactor == null) {
4415             throw new NullPointerException("null session or interactor");
4416         }
4417         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4418                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4419         // TODO: Switch to user app stacks here.
4420         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4421                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4422                 null, bOptions, false, userId, null, null);
4423     }
4424
4425     @Override
4426     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4427             throws RemoteException {
4428         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4429         synchronized (this) {
4430             ActivityRecord activity = getFocusedStack().topActivity();
4431             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4432                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4433             }
4434             if (mRunningVoice != null || activity.task.voiceSession != null
4435                     || activity.voiceSession != null) {
4436                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4437                 return;
4438             }
4439             if (activity.pendingVoiceInteractionStart) {
4440                 Slog.w(TAG, "Pending start of voice interaction already.");
4441                 return;
4442             }
4443             activity.pendingVoiceInteractionStart = true;
4444         }
4445         LocalServices.getService(VoiceInteractionManagerInternal.class)
4446                 .startLocalVoiceInteraction(callingActivity, options);
4447     }
4448
4449     @Override
4450     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4451         LocalServices.getService(VoiceInteractionManagerInternal.class)
4452                 .stopLocalVoiceInteraction(callingActivity);
4453     }
4454
4455     @Override
4456     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4457         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4458                 .supportsLocalVoiceInteraction();
4459     }
4460
4461     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4462             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4463         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4464         if (activityToCallback == null) return;
4465         activityToCallback.setVoiceSessionLocked(voiceSession);
4466
4467         // Inform the activity
4468         try {
4469             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4470                     voiceInteractor);
4471             long token = Binder.clearCallingIdentity();
4472             try {
4473                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4474             } finally {
4475                 Binder.restoreCallingIdentity(token);
4476             }
4477             // TODO: VI Should we cache the activity so that it's easier to find later
4478             // rather than scan through all the stacks and activities?
4479         } catch (RemoteException re) {
4480             activityToCallback.clearVoiceSessionLocked();
4481             // TODO: VI Should this terminate the voice session?
4482         }
4483     }
4484
4485     @Override
4486     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4487         synchronized (this) {
4488             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4489                 if (keepAwake) {
4490                     mVoiceWakeLock.acquire();
4491                 } else {
4492                     mVoiceWakeLock.release();
4493                 }
4494             }
4495         }
4496     }
4497
4498     @Override
4499     public boolean startNextMatchingActivity(IBinder callingActivity,
4500             Intent intent, Bundle bOptions) {
4501         // Refuse possible leaked file descriptors
4502         if (intent != null && intent.hasFileDescriptors() == true) {
4503             throw new IllegalArgumentException("File descriptors passed in Intent");
4504         }
4505         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4506
4507         synchronized (this) {
4508             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4509             if (r == null) {
4510                 ActivityOptions.abort(options);
4511                 return false;
4512             }
4513             if (r.app == null || r.app.thread == null) {
4514                 // The caller is not running...  d'oh!
4515                 ActivityOptions.abort(options);
4516                 return false;
4517             }
4518             intent = new Intent(intent);
4519             // The caller is not allowed to change the data.
4520             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4521             // And we are resetting to find the next component...
4522             intent.setComponent(null);
4523
4524             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4525
4526             ActivityInfo aInfo = null;
4527             try {
4528                 List<ResolveInfo> resolves =
4529                     AppGlobals.getPackageManager().queryIntentActivities(
4530                             intent, r.resolvedType,
4531                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4532                             UserHandle.getCallingUserId()).getList();
4533
4534                 // Look for the original activity in the list...
4535                 final int N = resolves != null ? resolves.size() : 0;
4536                 for (int i=0; i<N; i++) {
4537                     ResolveInfo rInfo = resolves.get(i);
4538                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4539                             && rInfo.activityInfo.name.equals(r.info.name)) {
4540                         // We found the current one...  the next matching is
4541                         // after it.
4542                         i++;
4543                         if (i<N) {
4544                             aInfo = resolves.get(i).activityInfo;
4545                         }
4546                         if (debug) {
4547                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4548                                     + "/" + r.info.name);
4549                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4550                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4551                         }
4552                         break;
4553                     }
4554                 }
4555             } catch (RemoteException e) {
4556             }
4557
4558             if (aInfo == null) {
4559                 // Nobody who is next!
4560                 ActivityOptions.abort(options);
4561                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4562                 return false;
4563             }
4564
4565             intent.setComponent(new ComponentName(
4566                     aInfo.applicationInfo.packageName, aInfo.name));
4567             intent.setFlags(intent.getFlags()&~(
4568                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4569                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4570                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4571                     Intent.FLAG_ACTIVITY_NEW_TASK));
4572
4573             // Okay now we need to start the new activity, replacing the
4574             // currently running activity.  This is a little tricky because
4575             // we want to start the new one as if the current one is finished,
4576             // but not finish the current one first so that there is no flicker.
4577             // And thus...
4578             final boolean wasFinishing = r.finishing;
4579             r.finishing = true;
4580
4581             // Propagate reply information over to the new activity.
4582             final ActivityRecord resultTo = r.resultTo;
4583             final String resultWho = r.resultWho;
4584             final int requestCode = r.requestCode;
4585             r.resultTo = null;
4586             if (resultTo != null) {
4587                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4588             }
4589
4590             final long origId = Binder.clearCallingIdentity();
4591             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4592                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4593                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4594                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4595                     false, false, null, null, null);
4596             Binder.restoreCallingIdentity(origId);
4597
4598             r.finishing = wasFinishing;
4599             if (res != ActivityManager.START_SUCCESS) {
4600                 return false;
4601             }
4602             return true;
4603         }
4604     }
4605
4606     @Override
4607     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4608         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4609             String msg = "Permission Denial: startActivityFromRecents called without " +
4610                     START_TASKS_FROM_RECENTS;
4611             Slog.w(TAG, msg);
4612             throw new SecurityException(msg);
4613         }
4614         final long origId = Binder.clearCallingIdentity();
4615         try {
4616             synchronized (this) {
4617                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4618             }
4619         } finally {
4620             Binder.restoreCallingIdentity(origId);
4621         }
4622     }
4623
4624     final int startActivityInPackage(int uid, String callingPackage,
4625             Intent intent, String resolvedType, IBinder resultTo,
4626             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4627             IActivityContainer container, TaskRecord inTask) {
4628
4629         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4630                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4631
4632         // TODO: Switch to user app stacks here.
4633         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4634                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4635                 null, null, null, bOptions, false, userId, container, inTask);
4636         return ret;
4637     }
4638
4639     @Override
4640     public final int startActivities(IApplicationThread caller, String callingPackage,
4641             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4642             int userId) {
4643         enforceNotIsolatedCaller("startActivities");
4644         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4645                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4646         // TODO: Switch to user app stacks here.
4647         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4648                 resolvedTypes, resultTo, bOptions, userId);
4649         return ret;
4650     }
4651
4652     final int startActivitiesInPackage(int uid, String callingPackage,
4653             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4654             Bundle bOptions, int userId) {
4655
4656         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4657                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4658         // TODO: Switch to user app stacks here.
4659         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4660                 resultTo, bOptions, userId);
4661         return ret;
4662     }
4663
4664     @Override
4665     public void reportActivityFullyDrawn(IBinder token) {
4666         synchronized (this) {
4667             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4668             if (r == null) {
4669                 return;
4670             }
4671             r.reportFullyDrawnLocked();
4672         }
4673     }
4674
4675     @Override
4676     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4677         synchronized (this) {
4678             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679             if (r == null) {
4680                 return;
4681             }
4682             TaskRecord task = r.task;
4683             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4684                 // Fixed screen orientation isn't supported when activities aren't in full screen
4685                 // mode.
4686                 return;
4687             }
4688             final long origId = Binder.clearCallingIdentity();
4689             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4690             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4691                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4692             if (config != null) {
4693                 r.frozenBeforeDestroy = true;
4694                 if (!updateConfigurationLocked(config, r, false)) {
4695                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4696                 }
4697             }
4698             Binder.restoreCallingIdentity(origId);
4699         }
4700     }
4701
4702     @Override
4703     public int getRequestedOrientation(IBinder token) {
4704         synchronized (this) {
4705             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4706             if (r == null) {
4707                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4708             }
4709             return mWindowManager.getAppOrientation(r.appToken);
4710         }
4711     }
4712
4713     /**
4714      * This is the internal entry point for handling Activity.finish().
4715      *
4716      * @param token The Binder token referencing the Activity we want to finish.
4717      * @param resultCode Result code, if any, from this Activity.
4718      * @param resultData Result data (Intent), if any, from this Activity.
4719      * @param finishTask Whether to finish the task associated with this Activity.
4720      *
4721      * @return Returns true if the activity successfully finished, or false if it is still running.
4722      */
4723     @Override
4724     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4725             int finishTask) {
4726         // Refuse possible leaked file descriptors
4727         if (resultData != null && resultData.hasFileDescriptors() == true) {
4728             throw new IllegalArgumentException("File descriptors passed in Intent");
4729         }
4730
4731         synchronized(this) {
4732             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4733             if (r == null) {
4734                 return true;
4735             }
4736             // Keep track of the root activity of the task before we finish it
4737             TaskRecord tr = r.task;
4738             ActivityRecord rootR = tr.getRootActivity();
4739             if (rootR == null) {
4740                 Slog.w(TAG, "Finishing task with all activities already finished");
4741             }
4742             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4743             // finish.
4744             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4745                     mStackSupervisor.isLastLockedTask(tr)) {
4746                 Slog.i(TAG, "Not finishing task in lock task mode");
4747                 mStackSupervisor.showLockTaskToast();
4748                 return false;
4749             }
4750             if (mController != null) {
4751                 // Find the first activity that is not finishing.
4752                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4753                 if (next != null) {
4754                     // ask watcher if this is allowed
4755                     boolean resumeOK = true;
4756                     try {
4757                         resumeOK = mController.activityResuming(next.packageName);
4758                     } catch (RemoteException e) {
4759                         mController = null;
4760                         Watchdog.getInstance().setActivityController(null);
4761                     }
4762
4763                     if (!resumeOK) {
4764                         Slog.i(TAG, "Not finishing activity because controller resumed");
4765                         return false;
4766                     }
4767                 }
4768             }
4769             final long origId = Binder.clearCallingIdentity();
4770             try {
4771                 boolean res;
4772                 final boolean finishWithRootActivity =
4773                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4774                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4775                         || (finishWithRootActivity && r == rootR)) {
4776                     // If requested, remove the task that is associated to this activity only if it
4777                     // was the root activity in the task. The result code and data is ignored
4778                     // because we don't support returning them across task boundaries. Also, to
4779                     // keep backwards compatibility we remove the task from recents when finishing
4780                     // task with root activity.
4781                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4782                     if (!res) {
4783                         Slog.i(TAG, "Removing task failed to finish activity");
4784                     }
4785                 } else {
4786                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4787                             resultData, "app-request", true);
4788                     if (!res) {
4789                         Slog.i(TAG, "Failed to finish by app-request");
4790                     }
4791                 }
4792                 return res;
4793             } finally {
4794                 Binder.restoreCallingIdentity(origId);
4795             }
4796         }
4797     }
4798
4799     @Override
4800     public final void finishHeavyWeightApp() {
4801         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4802                 != PackageManager.PERMISSION_GRANTED) {
4803             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4804                     + Binder.getCallingPid()
4805                     + ", uid=" + Binder.getCallingUid()
4806                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4807             Slog.w(TAG, msg);
4808             throw new SecurityException(msg);
4809         }
4810
4811         synchronized(this) {
4812             if (mHeavyWeightProcess == null) {
4813                 return;
4814             }
4815
4816             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4817             for (int i = 0; i < activities.size(); i++) {
4818                 ActivityRecord r = activities.get(i);
4819                 if (!r.finishing && r.isInStackLocked()) {
4820                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4821                             null, "finish-heavy", true);
4822                 }
4823             }
4824
4825             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                     mHeavyWeightProcess.userId, 0));
4827             mHeavyWeightProcess = null;
4828         }
4829     }
4830
4831     @Override
4832     public void crashApplication(int uid, int initialPid, String packageName,
4833             String message) {
4834         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4835                 != PackageManager.PERMISSION_GRANTED) {
4836             String msg = "Permission Denial: crashApplication() from pid="
4837                     + Binder.getCallingPid()
4838                     + ", uid=" + Binder.getCallingUid()
4839                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4840             Slog.w(TAG, msg);
4841             throw new SecurityException(msg);
4842         }
4843
4844         synchronized(this) {
4845             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4846         }
4847     }
4848
4849     @Override
4850     public final void finishSubActivity(IBinder token, String resultWho,
4851             int requestCode) {
4852         synchronized(this) {
4853             final long origId = Binder.clearCallingIdentity();
4854             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4855             if (r != null) {
4856                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4857             }
4858             Binder.restoreCallingIdentity(origId);
4859         }
4860     }
4861
4862     @Override
4863     public boolean finishActivityAffinity(IBinder token) {
4864         synchronized(this) {
4865             final long origId = Binder.clearCallingIdentity();
4866             try {
4867                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4868                 if (r == null) {
4869                     return false;
4870                 }
4871
4872                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4873                 // can finish.
4874                 final TaskRecord task = r.task;
4875                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4876                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4877                     mStackSupervisor.showLockTaskToast();
4878                     return false;
4879                 }
4880                 return task.stack.finishActivityAffinityLocked(r);
4881             } finally {
4882                 Binder.restoreCallingIdentity(origId);
4883             }
4884         }
4885     }
4886
4887     @Override
4888     public void finishVoiceTask(IVoiceInteractionSession session) {
4889         synchronized (this) {
4890             final long origId = Binder.clearCallingIdentity();
4891             try {
4892                 // TODO: VI Consider treating local voice interactions and voice tasks
4893                 // differently here
4894                 mStackSupervisor.finishVoiceTask(session);
4895             } finally {
4896                 Binder.restoreCallingIdentity(origId);
4897             }
4898         }
4899
4900     }
4901
4902     @Override
4903     public boolean releaseActivityInstance(IBinder token) {
4904         synchronized(this) {
4905             final long origId = Binder.clearCallingIdentity();
4906             try {
4907                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4908                 if (r == null) {
4909                     return false;
4910                 }
4911                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4912             } finally {
4913                 Binder.restoreCallingIdentity(origId);
4914             }
4915         }
4916     }
4917
4918     @Override
4919     public void releaseSomeActivities(IApplicationThread appInt) {
4920         synchronized(this) {
4921             final long origId = Binder.clearCallingIdentity();
4922             try {
4923                 ProcessRecord app = getRecordForAppLocked(appInt);
4924                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4925             } finally {
4926                 Binder.restoreCallingIdentity(origId);
4927             }
4928         }
4929     }
4930
4931     @Override
4932     public boolean willActivityBeVisible(IBinder token) {
4933         synchronized(this) {
4934             ActivityStack stack = ActivityRecord.getStackLocked(token);
4935             if (stack != null) {
4936                 return stack.willActivityBeVisibleLocked(token);
4937             }
4938             return false;
4939         }
4940     }
4941
4942     @Override
4943     public void overridePendingTransition(IBinder token, String packageName,
4944             int enterAnim, int exitAnim) {
4945         synchronized(this) {
4946             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4947             if (self == null) {
4948                 return;
4949             }
4950
4951             final long origId = Binder.clearCallingIdentity();
4952
4953             if (self.state == ActivityState.RESUMED
4954                     || self.state == ActivityState.PAUSING) {
4955                 mWindowManager.overridePendingAppTransition(packageName,
4956                         enterAnim, exitAnim, null);
4957             }
4958
4959             Binder.restoreCallingIdentity(origId);
4960         }
4961     }
4962
4963     /**
4964      * Main function for removing an existing process from the activity manager
4965      * as a result of that process going away.  Clears out all connections
4966      * to the process.
4967      */
4968     private final void handleAppDiedLocked(ProcessRecord app,
4969             boolean restarting, boolean allowRestart) {
4970         int pid = app.pid;
4971         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4972         if (!kept && !restarting) {
4973             removeLruProcessLocked(app);
4974             if (pid > 0) {
4975                 ProcessList.remove(pid);
4976             }
4977         }
4978
4979         if (mProfileProc == app) {
4980             clearProfilerLocked();
4981         }
4982
4983         // Remove this application's activities from active lists.
4984         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4985
4986         app.activities.clear();
4987
4988         if (app.instrumentationClass != null) {
4989             Slog.w(TAG, "Crash of app " + app.processName
4990                   + " running instrumentation " + app.instrumentationClass);
4991             Bundle info = new Bundle();
4992             info.putString("shortMsg", "Process crashed.");
4993             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4994         }
4995
4996         if (!restarting && hasVisibleActivities
4997                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4998             // If there was nothing to resume, and we are not already restarting this process, but
4999             // there is a visible activity that is hosted by the process...  then make sure all
5000             // visible activities are running, taking care of restarting this process.
5001             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5002         }
5003     }
5004
5005     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5006         IBinder threadBinder = thread.asBinder();
5007         // Find the application record.
5008         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5009             ProcessRecord rec = mLruProcesses.get(i);
5010             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5011                 return i;
5012             }
5013         }
5014         return -1;
5015     }
5016
5017     final ProcessRecord getRecordForAppLocked(
5018             IApplicationThread thread) {
5019         if (thread == null) {
5020             return null;
5021         }
5022
5023         int appIndex = getLRURecordIndexForAppLocked(thread);
5024         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5025     }
5026
5027     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5028         // If there are no longer any background processes running,
5029         // and the app that died was not running instrumentation,
5030         // then tell everyone we are now low on memory.
5031         boolean haveBg = false;
5032         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5033             ProcessRecord rec = mLruProcesses.get(i);
5034             if (rec.thread != null
5035                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5036                 haveBg = true;
5037                 break;
5038             }
5039         }
5040
5041         if (!haveBg) {
5042             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5043             if (doReport) {
5044                 long now = SystemClock.uptimeMillis();
5045                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5046                     doReport = false;
5047                 } else {
5048                     mLastMemUsageReportTime = now;
5049                 }
5050             }
5051             final ArrayList<ProcessMemInfo> memInfos
5052                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5053             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5054             long now = SystemClock.uptimeMillis();
5055             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5056                 ProcessRecord rec = mLruProcesses.get(i);
5057                 if (rec == dyingProc || rec.thread == null) {
5058                     continue;
5059                 }
5060                 if (doReport) {
5061                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5062                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5063                 }
5064                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5065                     // The low memory report is overriding any current
5066                     // state for a GC request.  Make sure to do
5067                     // heavy/important/visible/foreground processes first.
5068                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5069                         rec.lastRequestedGc = 0;
5070                     } else {
5071                         rec.lastRequestedGc = rec.lastLowMemory;
5072                     }
5073                     rec.reportLowMemory = true;
5074                     rec.lastLowMemory = now;
5075                     mProcessesToGc.remove(rec);
5076                     addProcessToGcListLocked(rec);
5077                 }
5078             }
5079             if (doReport) {
5080                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5081                 mHandler.sendMessage(msg);
5082             }
5083             scheduleAppGcsLocked();
5084         }
5085     }
5086
5087     final void appDiedLocked(ProcessRecord app) {
5088        appDiedLocked(app, app.pid, app.thread, false);
5089     }
5090
5091     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5092             boolean fromBinderDied) {
5093         // First check if this ProcessRecord is actually active for the pid.
5094         synchronized (mPidsSelfLocked) {
5095             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5096             if (curProc != app) {
5097                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5098                 return;
5099             }
5100         }
5101
5102         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5103         synchronized (stats) {
5104             stats.noteProcessDiedLocked(app.info.uid, pid);
5105         }
5106
5107         if (!app.killed) {
5108             if (!fromBinderDied) {
5109                 Process.killProcessQuiet(pid);
5110             }
5111             killProcessGroup(app.uid, pid);
5112             app.killed = true;
5113         }
5114
5115         // Clean up already done if the process has been re-started.
5116         if (app.pid == pid && app.thread != null &&
5117                 app.thread.asBinder() == thread.asBinder()) {
5118             boolean doLowMem = app.instrumentationClass == null;
5119             boolean doOomAdj = doLowMem;
5120             if (!app.killedByAm) {
5121                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5122                         + ") has died");
5123                 mAllowLowerMemLevel = true;
5124             } else {
5125                 // Note that we always want to do oom adj to update our state with the
5126                 // new number of procs.
5127                 mAllowLowerMemLevel = false;
5128                 doLowMem = false;
5129             }
5130             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5131             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5132                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5133             handleAppDiedLocked(app, false, true);
5134
5135             if (doOomAdj) {
5136                 updateOomAdjLocked();
5137             }
5138             if (doLowMem) {
5139                 doLowMemReportIfNeededLocked(app);
5140             }
5141         } else if (app.pid != pid) {
5142             // A new process has already been started.
5143             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5144                     + ") has died and restarted (pid " + app.pid + ").");
5145             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5146         } else if (DEBUG_PROCESSES) {
5147             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5148                     + thread.asBinder());
5149         }
5150     }
5151
5152     /**
5153      * If a stack trace dump file is configured, dump process stack traces.
5154      * @param clearTraces causes the dump file to be erased prior to the new
5155      *    traces being written, if true; when false, the new traces will be
5156      *    appended to any existing file content.
5157      * @param firstPids of dalvik VM processes to dump stack traces for first
5158      * @param lastPids of dalvik VM processes to dump stack traces for last
5159      * @param nativeProcs optional list of native process names to dump stack crawls
5160      * @return file containing stack traces, or null if no dump file is configured
5161      */
5162     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5163             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5164         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5165         if (tracesPath == null || tracesPath.length() == 0) {
5166             return null;
5167         }
5168
5169         File tracesFile = new File(tracesPath);
5170         try {
5171             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5172             tracesFile.createNewFile();
5173             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5174         } catch (IOException e) {
5175             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5176             return null;
5177         }
5178
5179         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5180         return tracesFile;
5181     }
5182
5183     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5184             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5185         // Use a FileObserver to detect when traces finish writing.
5186         // The order of traces is considered important to maintain for legibility.
5187         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5188             @Override
5189             public synchronized void onEvent(int event, String path) { notify(); }
5190         };
5191
5192         try {
5193             observer.startWatching();
5194
5195             // First collect all of the stacks of the most important pids.
5196             if (firstPids != null) {
5197                 try {
5198                     int num = firstPids.size();
5199                     for (int i = 0; i < num; i++) {
5200                         synchronized (observer) {
5201                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5202                                     + firstPids.get(i));
5203                             final long sime = SystemClock.elapsedRealtime();
5204                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5205                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5206                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5207                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5208                         }
5209                     }
5210                 } catch (InterruptedException e) {
5211                     Slog.wtf(TAG, e);
5212                 }
5213             }
5214
5215             // Next collect the stacks of the native pids
5216             if (nativeProcs != null) {
5217                 int[] pids = Process.getPidsForCommands(nativeProcs);
5218                 if (pids != null) {
5219                     for (int pid : pids) {
5220                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5221                         final long sime = SystemClock.elapsedRealtime();
5222                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5223                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5224                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5225                     }
5226                 }
5227             }
5228
5229             // Lastly, measure CPU usage.
5230             if (processCpuTracker != null) {
5231                 processCpuTracker.init();
5232                 System.gc();
5233                 processCpuTracker.update();
5234                 try {
5235                     synchronized (processCpuTracker) {
5236                         processCpuTracker.wait(500); // measure over 1/2 second.
5237                     }
5238                 } catch (InterruptedException e) {
5239                 }
5240                 processCpuTracker.update();
5241
5242                 // We'll take the stack crawls of just the top apps using CPU.
5243                 final int N = processCpuTracker.countWorkingStats();
5244                 int numProcs = 0;
5245                 for (int i=0; i<N && numProcs<5; i++) {
5246                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5247                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5248                         numProcs++;
5249                         try {
5250                             synchronized (observer) {
5251                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5252                                         + stats.pid);
5253                                 final long stime = SystemClock.elapsedRealtime();
5254                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5255                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5256                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5257                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5258                             }
5259                         } catch (InterruptedException e) {
5260                             Slog.wtf(TAG, e);
5261                         }
5262                     } else if (DEBUG_ANR) {
5263                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5264                                 + stats.pid);
5265                     }
5266                 }
5267             }
5268         } finally {
5269             observer.stopWatching();
5270         }
5271     }
5272
5273     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5274         if (true || IS_USER_BUILD) {
5275             return;
5276         }
5277         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5278         if (tracesPath == null || tracesPath.length() == 0) {
5279             return;
5280         }
5281
5282         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5283         StrictMode.allowThreadDiskWrites();
5284         try {
5285             final File tracesFile = new File(tracesPath);
5286             final File tracesDir = tracesFile.getParentFile();
5287             final File tracesTmp = new File(tracesDir, "__tmp__");
5288             try {
5289                 if (tracesFile.exists()) {
5290                     tracesTmp.delete();
5291                     tracesFile.renameTo(tracesTmp);
5292                 }
5293                 StringBuilder sb = new StringBuilder();
5294                 Time tobj = new Time();
5295                 tobj.set(System.currentTimeMillis());
5296                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5297                 sb.append(": ");
5298                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5299                 sb.append(" since ");
5300                 sb.append(msg);
5301                 FileOutputStream fos = new FileOutputStream(tracesFile);
5302                 fos.write(sb.toString().getBytes());
5303                 if (app == null) {
5304                     fos.write("\n*** No application process!".getBytes());
5305                 }
5306                 fos.close();
5307                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5308             } catch (IOException e) {
5309                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5310                 return;
5311             }
5312
5313             if (app != null) {
5314                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5315                 firstPids.add(app.pid);
5316                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5317             }
5318
5319             File lastTracesFile = null;
5320             File curTracesFile = null;
5321             for (int i=9; i>=0; i--) {
5322                 String name = String.format(Locale.US, "slow%02d.txt", i);
5323                 curTracesFile = new File(tracesDir, name);
5324                 if (curTracesFile.exists()) {
5325                     if (lastTracesFile != null) {
5326                         curTracesFile.renameTo(lastTracesFile);
5327                     } else {
5328                         curTracesFile.delete();
5329                     }
5330                 }
5331                 lastTracesFile = curTracesFile;
5332             }
5333             tracesFile.renameTo(curTracesFile);
5334             if (tracesTmp.exists()) {
5335                 tracesTmp.renameTo(tracesFile);
5336             }
5337         } finally {
5338             StrictMode.setThreadPolicy(oldPolicy);
5339         }
5340     }
5341
5342     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5343         if (!mLaunchWarningShown) {
5344             mLaunchWarningShown = true;
5345             mUiHandler.post(new Runnable() {
5346                 @Override
5347                 public void run() {
5348                     synchronized (ActivityManagerService.this) {
5349                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5350                         d.show();
5351                         mUiHandler.postDelayed(new Runnable() {
5352                             @Override
5353                             public void run() {
5354                                 synchronized (ActivityManagerService.this) {
5355                                     d.dismiss();
5356                                     mLaunchWarningShown = false;
5357                                 }
5358                             }
5359                         }, 4000);
5360                     }
5361                 }
5362             });
5363         }
5364     }
5365
5366     @Override
5367     public boolean clearApplicationUserData(final String packageName,
5368             final IPackageDataObserver observer, int userId) {
5369         enforceNotIsolatedCaller("clearApplicationUserData");
5370         int uid = Binder.getCallingUid();
5371         int pid = Binder.getCallingPid();
5372         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5373                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5374
5375         final DevicePolicyManagerInternal dpmi = LocalServices
5376                 .getService(DevicePolicyManagerInternal.class);
5377         if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5378             throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5379         }
5380
5381         long callingId = Binder.clearCallingIdentity();
5382         try {
5383             IPackageManager pm = AppGlobals.getPackageManager();
5384             int pkgUid = -1;
5385             synchronized(this) {
5386                 try {
5387                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5388                 } catch (RemoteException e) {
5389                 }
5390                 if (pkgUid == -1) {
5391                     Slog.w(TAG, "Invalid packageName: " + packageName);
5392                     if (observer != null) {
5393                         try {
5394                             observer.onRemoveCompleted(packageName, false);
5395                         } catch (RemoteException e) {
5396                             Slog.i(TAG, "Observer no longer exists.");
5397                         }
5398                     }
5399                     return false;
5400                 }
5401                 if (uid == pkgUid || checkComponentPermission(
5402                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5403                         pid, uid, -1, true)
5404                         == PackageManager.PERMISSION_GRANTED) {
5405                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5406                 } else {
5407                     throw new SecurityException("PID " + pid + " does not have permission "
5408                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5409                                     + " of package " + packageName);
5410                 }
5411
5412                 // Remove all tasks match the cleared application package and user
5413                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5414                     final TaskRecord tr = mRecentTasks.get(i);
5415                     final String taskPackageName =
5416                             tr.getBaseIntent().getComponent().getPackageName();
5417                     if (tr.userId != userId) continue;
5418                     if (!taskPackageName.equals(packageName)) continue;
5419                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5420                 }
5421             }
5422
5423             final int pkgUidF = pkgUid;
5424             final int userIdF = userId;
5425             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5426                 @Override
5427                 public void onRemoveCompleted(String packageName, boolean succeeded)
5428                         throws RemoteException {
5429                     synchronized (ActivityManagerService.this) {
5430                         finishForceStopPackageLocked(packageName, pkgUidF);
5431                     }
5432
5433                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5434                             Uri.fromParts("package", packageName, null));
5435                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5436                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5437                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438                             null, null, 0, null, null, null, null, false, false, userIdF);
5439
5440                     if (observer != null) {
5441                         observer.onRemoveCompleted(packageName, succeeded);
5442                     }
5443                 }
5444             };
5445
5446             try {
5447                 // Clear application user data
5448                 pm.clearApplicationUserData(packageName, localObserver, userId);
5449
5450                 synchronized(this) {
5451                     // Remove all permissions granted from/to this package
5452                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5453                 }
5454
5455                 // Remove all zen rules created by this package; revoke it's zen access.
5456                 INotificationManager inm = NotificationManager.getService();
5457                 inm.removeAutomaticZenRules(packageName);
5458                 inm.setNotificationPolicyAccessGranted(packageName, false);
5459
5460             } catch (RemoteException e) {
5461             }
5462         } finally {
5463             Binder.restoreCallingIdentity(callingId);
5464         }
5465         return true;
5466     }
5467
5468     @Override
5469     public void killBackgroundProcesses(final String packageName, int userId) {
5470         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5471                 != PackageManager.PERMISSION_GRANTED &&
5472                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5473                         != PackageManager.PERMISSION_GRANTED) {
5474             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5475                     + Binder.getCallingPid()
5476                     + ", uid=" + Binder.getCallingUid()
5477                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5478             Slog.w(TAG, msg);
5479             throw new SecurityException(msg);
5480         }
5481
5482         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5483                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5484         long callingId = Binder.clearCallingIdentity();
5485         try {
5486             IPackageManager pm = AppGlobals.getPackageManager();
5487             synchronized(this) {
5488                 int appId = -1;
5489                 try {
5490                     appId = UserHandle.getAppId(
5491                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5492                 } catch (RemoteException e) {
5493                 }
5494                 if (appId == -1) {
5495                     Slog.w(TAG, "Invalid packageName: " + packageName);
5496                     return;
5497                 }
5498                 killPackageProcessesLocked(packageName, appId, userId,
5499                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5500             }
5501         } finally {
5502             Binder.restoreCallingIdentity(callingId);
5503         }
5504     }
5505
5506     @Override
5507     public void killAllBackgroundProcesses() {
5508         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5509                 != PackageManager.PERMISSION_GRANTED) {
5510             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5511                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5512                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5513             Slog.w(TAG, msg);
5514             throw new SecurityException(msg);
5515         }
5516
5517         final long callingId = Binder.clearCallingIdentity();
5518         try {
5519             synchronized (this) {
5520                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5521                 final int NP = mProcessNames.getMap().size();
5522                 for (int ip = 0; ip < NP; ip++) {
5523                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524                     final int NA = apps.size();
5525                     for (int ia = 0; ia < NA; ia++) {
5526                         final ProcessRecord app = apps.valueAt(ia);
5527                         if (app.persistent) {
5528                             // We don't kill persistent processes.
5529                             continue;
5530                         }
5531                         if (app.removed) {
5532                             procs.add(app);
5533                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5534                             app.removed = true;
5535                             procs.add(app);
5536                         }
5537                     }
5538                 }
5539
5540                 final int N = procs.size();
5541                 for (int i = 0; i < N; i++) {
5542                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5543                 }
5544
5545                 mAllowLowerMemLevel = true;
5546
5547                 updateOomAdjLocked();
5548                 doLowMemReportIfNeededLocked(null);
5549             }
5550         } finally {
5551             Binder.restoreCallingIdentity(callingId);
5552         }
5553     }
5554
5555     /**
5556      * Kills all background processes, except those matching any of the
5557      * specified properties.
5558      *
5559      * @param minTargetSdk the target SDK version at or above which to preserve
5560      *                     processes, or {@code -1} to ignore the target SDK
5561      * @param maxProcState the process state at or below which to preserve
5562      *                     processes, or {@code -1} to ignore the process state
5563      */
5564     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5565         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5566                 != PackageManager.PERMISSION_GRANTED) {
5567             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5568                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5569                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5570             Slog.w(TAG, msg);
5571             throw new SecurityException(msg);
5572         }
5573
5574         final long callingId = Binder.clearCallingIdentity();
5575         try {
5576             synchronized (this) {
5577                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5578                 final int NP = mProcessNames.getMap().size();
5579                 for (int ip = 0; ip < NP; ip++) {
5580                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5581                     final int NA = apps.size();
5582                     for (int ia = 0; ia < NA; ia++) {
5583                         final ProcessRecord app = apps.valueAt(ia);
5584                         if (app.removed) {
5585                             procs.add(app);
5586                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5587                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5588                             app.removed = true;
5589                             procs.add(app);
5590                         }
5591                     }
5592                 }
5593
5594                 final int N = procs.size();
5595                 for (int i = 0; i < N; i++) {
5596                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5597                 }
5598             }
5599         } finally {
5600             Binder.restoreCallingIdentity(callingId);
5601         }
5602     }
5603
5604     @Override
5605     public void forceStopPackage(final String packageName, int userId) {
5606         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5607                 != PackageManager.PERMISSION_GRANTED) {
5608             String msg = "Permission Denial: forceStopPackage() from pid="
5609                     + Binder.getCallingPid()
5610                     + ", uid=" + Binder.getCallingUid()
5611                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5612             Slog.w(TAG, msg);
5613             throw new SecurityException(msg);
5614         }
5615         final int callingPid = Binder.getCallingPid();
5616         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5617                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5618         long callingId = Binder.clearCallingIdentity();
5619         try {
5620             IPackageManager pm = AppGlobals.getPackageManager();
5621             synchronized(this) {
5622                 int[] users = userId == UserHandle.USER_ALL
5623                         ? mUserController.getUsers() : new int[] { userId };
5624                 for (int user : users) {
5625                     int pkgUid = -1;
5626                     try {
5627                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5628                                 user);
5629                     } catch (RemoteException e) {
5630                     }
5631                     if (pkgUid == -1) {
5632                         Slog.w(TAG, "Invalid packageName: " + packageName);
5633                         continue;
5634                     }
5635                     try {
5636                         pm.setPackageStoppedState(packageName, true, user);
5637                     } catch (RemoteException e) {
5638                     } catch (IllegalArgumentException e) {
5639                         Slog.w(TAG, "Failed trying to unstop package "
5640                                 + packageName + ": " + e);
5641                     }
5642                     if (mUserController.isUserRunningLocked(user, 0)) {
5643                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5644                         finishForceStopPackageLocked(packageName, pkgUid);
5645                     }
5646                 }
5647             }
5648         } finally {
5649             Binder.restoreCallingIdentity(callingId);
5650         }
5651     }
5652
5653     @Override
5654     public void addPackageDependency(String packageName) {
5655         synchronized (this) {
5656             int callingPid = Binder.getCallingPid();
5657             if (callingPid == Process.myPid()) {
5658                 //  Yeah, um, no.
5659                 return;
5660             }
5661             ProcessRecord proc;
5662             synchronized (mPidsSelfLocked) {
5663                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5664             }
5665             if (proc != null) {
5666                 if (proc.pkgDeps == null) {
5667                     proc.pkgDeps = new ArraySet<String>(1);
5668                 }
5669                 proc.pkgDeps.add(packageName);
5670             }
5671         }
5672     }
5673
5674     /*
5675      * The pkg name and app id have to be specified.
5676      */
5677     @Override
5678     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5679         if (pkg == null) {
5680             return;
5681         }
5682         // Make sure the uid is valid.
5683         if (appid < 0) {
5684             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5685             return;
5686         }
5687         int callerUid = Binder.getCallingUid();
5688         // Only the system server can kill an application
5689         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5690             // Post an aysnc message to kill the application
5691             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5692             msg.arg1 = appid;
5693             msg.arg2 = 0;
5694             Bundle bundle = new Bundle();
5695             bundle.putString("pkg", pkg);
5696             bundle.putString("reason", reason);
5697             msg.obj = bundle;
5698             mHandler.sendMessage(msg);
5699         } else {
5700             throw new SecurityException(callerUid + " cannot kill pkg: " +
5701                     pkg);
5702         }
5703     }
5704
5705     @Override
5706     public void closeSystemDialogs(String reason) {
5707         enforceNotIsolatedCaller("closeSystemDialogs");
5708
5709         final int pid = Binder.getCallingPid();
5710         final int uid = Binder.getCallingUid();
5711         final long origId = Binder.clearCallingIdentity();
5712         try {
5713             synchronized (this) {
5714                 // Only allow this from foreground processes, so that background
5715                 // applications can't abuse it to prevent system UI from being shown.
5716                 if (uid >= Process.FIRST_APPLICATION_UID) {
5717                     ProcessRecord proc;
5718                     synchronized (mPidsSelfLocked) {
5719                         proc = mPidsSelfLocked.get(pid);
5720                     }
5721                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5722                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5723                                 + " from background process " + proc);
5724                         return;
5725                     }
5726                 }
5727                 closeSystemDialogsLocked(reason);
5728             }
5729         } finally {
5730             Binder.restoreCallingIdentity(origId);
5731         }
5732     }
5733
5734     void closeSystemDialogsLocked(String reason) {
5735         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5736         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5737                 | Intent.FLAG_RECEIVER_FOREGROUND);
5738         if (reason != null) {
5739             intent.putExtra("reason", reason);
5740         }
5741         mWindowManager.closeSystemDialogs(reason);
5742
5743         mStackSupervisor.closeSystemDialogsLocked();
5744
5745         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5746                 AppOpsManager.OP_NONE, null, false, false,
5747                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5748     }
5749
5750     @Override
5751     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5752         enforceNotIsolatedCaller("getProcessMemoryInfo");
5753         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5754         for (int i=pids.length-1; i>=0; i--) {
5755             ProcessRecord proc;
5756             int oomAdj;
5757             synchronized (this) {
5758                 synchronized (mPidsSelfLocked) {
5759                     proc = mPidsSelfLocked.get(pids[i]);
5760                     oomAdj = proc != null ? proc.setAdj : 0;
5761                 }
5762             }
5763             infos[i] = new Debug.MemoryInfo();
5764             Debug.getMemoryInfo(pids[i], infos[i]);
5765             if (proc != null) {
5766                 synchronized (this) {
5767                     if (proc.thread != null && proc.setAdj == oomAdj) {
5768                         // Record this for posterity if the process has been stable.
5769                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5770                                 infos[i].getTotalUss(), false, proc.pkgList);
5771                     }
5772                 }
5773             }
5774         }
5775         return infos;
5776     }
5777
5778     @Override
5779     public long[] getProcessPss(int[] pids) {
5780         enforceNotIsolatedCaller("getProcessPss");
5781         long[] pss = new long[pids.length];
5782         for (int i=pids.length-1; i>=0; i--) {
5783             ProcessRecord proc;
5784             int oomAdj;
5785             synchronized (this) {
5786                 synchronized (mPidsSelfLocked) {
5787                     proc = mPidsSelfLocked.get(pids[i]);
5788                     oomAdj = proc != null ? proc.setAdj : 0;
5789                 }
5790             }
5791             long[] tmpUss = new long[1];
5792             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5793             if (proc != null) {
5794                 synchronized (this) {
5795                     if (proc.thread != null && proc.setAdj == oomAdj) {
5796                         // Record this for posterity if the process has been stable.
5797                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5798                     }
5799                 }
5800             }
5801         }
5802         return pss;
5803     }
5804
5805     @Override
5806     public void killApplicationProcess(String processName, int uid) {
5807         if (processName == null) {
5808             return;
5809         }
5810
5811         int callerUid = Binder.getCallingUid();
5812         // Only the system server can kill an application
5813         if (callerUid == Process.SYSTEM_UID) {
5814             synchronized (this) {
5815                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5816                 if (app != null && app.thread != null) {
5817                     try {
5818                         app.thread.scheduleSuicide();
5819                     } catch (RemoteException e) {
5820                         // If the other end already died, then our work here is done.
5821                     }
5822                 } else {
5823                     Slog.w(TAG, "Process/uid not found attempting kill of "
5824                             + processName + " / " + uid);
5825                 }
5826             }
5827         } else {
5828             throw new SecurityException(callerUid + " cannot kill app process: " +
5829                     processName);
5830         }
5831     }
5832
5833     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5834         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5835                 false, true, false, false, UserHandle.getUserId(uid), reason);
5836     }
5837
5838     private void finishForceStopPackageLocked(final String packageName, int uid) {
5839         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5840                 Uri.fromParts("package", packageName, null));
5841         if (!mProcessesReady) {
5842             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5843                     | Intent.FLAG_RECEIVER_FOREGROUND);
5844         }
5845         intent.putExtra(Intent.EXTRA_UID, uid);
5846         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5847         broadcastIntentLocked(null, null, intent,
5848                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5849                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5850     }
5851
5852
5853     private final boolean killPackageProcessesLocked(String packageName, int appId,
5854             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5855             boolean doit, boolean evenPersistent, String reason) {
5856         ArrayList<ProcessRecord> procs = new ArrayList<>();
5857
5858         // Remove all processes this package may have touched: all with the
5859         // same UID (except for the system or root user), and all whose name
5860         // matches the package name.
5861         final int NP = mProcessNames.getMap().size();
5862         for (int ip=0; ip<NP; ip++) {
5863             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5864             final int NA = apps.size();
5865             for (int ia=0; ia<NA; ia++) {
5866                 ProcessRecord app = apps.valueAt(ia);
5867                 if (app.persistent && !evenPersistent) {
5868                     // we don't kill persistent processes
5869                     continue;
5870                 }
5871                 if (app.removed) {
5872                     if (doit) {
5873                         procs.add(app);
5874                     }
5875                     continue;
5876                 }
5877
5878                 // Skip process if it doesn't meet our oom adj requirement.
5879                 if (app.setAdj < minOomAdj) {
5880                     continue;
5881                 }
5882
5883                 // If no package is specified, we call all processes under the
5884                 // give user id.
5885                 if (packageName == null) {
5886                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5887                         continue;
5888                     }
5889                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5890                         continue;
5891                     }
5892                 // Package has been specified, we want to hit all processes
5893                 // that match it.  We need to qualify this by the processes
5894                 // that are running under the specified app and user ID.
5895                 } else {
5896                     final boolean isDep = app.pkgDeps != null
5897                             && app.pkgDeps.contains(packageName);
5898                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5899                         continue;
5900                     }
5901                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5902                         continue;
5903                     }
5904                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5905                         continue;
5906                     }
5907                 }
5908
5909                 // Process has passed all conditions, kill it!
5910                 if (!doit) {
5911                     return true;
5912                 }
5913                 app.removed = true;
5914                 procs.add(app);
5915             }
5916         }
5917
5918         int N = procs.size();
5919         for (int i=0; i<N; i++) {
5920             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5921         }
5922         updateOomAdjLocked();
5923         return N > 0;
5924     }
5925
5926     private void cleanupDisabledPackageComponentsLocked(
5927             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5928
5929         Set<String> disabledClasses = null;
5930         boolean packageDisabled = false;
5931         IPackageManager pm = AppGlobals.getPackageManager();
5932
5933         if (changedClasses == null) {
5934             // Nothing changed...
5935             return;
5936         }
5937
5938         // Determine enable/disable state of the package and its components.
5939         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5940         for (int i = changedClasses.length - 1; i >= 0; i--) {
5941             final String changedClass = changedClasses[i];
5942
5943             if (changedClass.equals(packageName)) {
5944                 try {
5945                     // Entire package setting changed
5946                     enabled = pm.getApplicationEnabledSetting(packageName,
5947                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5948                 } catch (Exception e) {
5949                     // No such package/component; probably racing with uninstall.  In any
5950                     // event it means we have nothing further to do here.
5951                     return;
5952                 }
5953                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5954                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5955                 if (packageDisabled) {
5956                     // Entire package is disabled.
5957                     // No need to continue to check component states.
5958                     disabledClasses = null;
5959                     break;
5960                 }
5961             } else {
5962                 try {
5963                     enabled = pm.getComponentEnabledSetting(
5964                             new ComponentName(packageName, changedClass),
5965                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5966                 } catch (Exception e) {
5967                     // As above, probably racing with uninstall.
5968                     return;
5969                 }
5970                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5971                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5972                     if (disabledClasses == null) {
5973                         disabledClasses = new ArraySet<>(changedClasses.length);
5974                     }
5975                     disabledClasses.add(changedClass);
5976                 }
5977             }
5978         }
5979
5980         if (!packageDisabled && disabledClasses == null) {
5981             // Nothing to do here...
5982             return;
5983         }
5984
5985         // Clean-up disabled activities.
5986         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5987                 packageName, disabledClasses, true, false, userId) && mBooted) {
5988             mStackSupervisor.resumeFocusedStackTopActivityLocked();
5989             mStackSupervisor.scheduleIdleLocked();
5990         }
5991
5992         // Clean-up disabled tasks
5993         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5994
5995         // Clean-up disabled services.
5996         mServices.bringDownDisabledPackageServicesLocked(
5997                 packageName, disabledClasses, userId, false, killProcess, true);
5998
5999         // Clean-up disabled providers.
6000         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6001         mProviderMap.collectPackageProvidersLocked(
6002                 packageName, disabledClasses, true, false, userId, providers);
6003         for (int i = providers.size() - 1; i >= 0; i--) {
6004             removeDyingProviderLocked(null, providers.get(i), true);
6005         }
6006
6007         // Clean-up disabled broadcast receivers.
6008         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6009             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6010                     packageName, disabledClasses, userId, true);
6011         }
6012
6013     }
6014
6015     final boolean clearBroadcastQueueForUserLocked(int userId) {
6016         boolean didSomething = false;
6017         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019                     null, null, userId, true);
6020         }
6021         return didSomething;
6022     }
6023
6024     final boolean forceStopPackageLocked(String packageName, int appId,
6025             boolean callerWillRestart, boolean purgeCache, boolean doit,
6026             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6027         int i;
6028
6029         if (userId == UserHandle.USER_ALL && packageName == null) {
6030             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6031         }
6032
6033         if (appId < 0 && packageName != null) {
6034             try {
6035                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6036                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6037             } catch (RemoteException e) {
6038             }
6039         }
6040
6041         if (doit) {
6042             if (packageName != null) {
6043                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6044                         + " user=" + userId + ": " + reason);
6045             } else {
6046                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6047             }
6048
6049             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6050         }
6051
6052         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6053                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6054                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6055
6056         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6057                 packageName, null, doit, evenPersistent, userId)) {
6058             if (!doit) {
6059                 return true;
6060             }
6061             didSomething = true;
6062         }
6063
6064         if (mServices.bringDownDisabledPackageServicesLocked(
6065                 packageName, null, userId, evenPersistent, true, doit)) {
6066             if (!doit) {
6067                 return true;
6068             }
6069             didSomething = true;
6070         }
6071
6072         if (packageName == null) {
6073             // Remove all sticky broadcasts from this user.
6074             mStickyBroadcasts.remove(userId);
6075         }
6076
6077         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6078         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6079                 userId, providers)) {
6080             if (!doit) {
6081                 return true;
6082             }
6083             didSomething = true;
6084         }
6085         for (i = providers.size() - 1; i >= 0; i--) {
6086             removeDyingProviderLocked(null, providers.get(i), true);
6087         }
6088
6089         // Remove transient permissions granted from/to this package/user
6090         removeUriPermissionsForPackageLocked(packageName, userId, false);
6091
6092         if (doit) {
6093             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6094                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6095                         packageName, null, userId, doit);
6096             }
6097         }
6098
6099         if (packageName == null || uninstalling) {
6100             // Remove pending intents.  For now we only do this when force
6101             // stopping users, because we have some problems when doing this
6102             // for packages -- app widgets are not currently cleaned up for
6103             // such packages, so they can be left with bad pending intents.
6104             if (mIntentSenderRecords.size() > 0) {
6105                 Iterator<WeakReference<PendingIntentRecord>> it
6106                         = mIntentSenderRecords.values().iterator();
6107                 while (it.hasNext()) {
6108                     WeakReference<PendingIntentRecord> wpir = it.next();
6109                     if (wpir == null) {
6110                         it.remove();
6111                         continue;
6112                     }
6113                     PendingIntentRecord pir = wpir.get();
6114                     if (pir == null) {
6115                         it.remove();
6116                         continue;
6117                     }
6118                     if (packageName == null) {
6119                         // Stopping user, remove all objects for the user.
6120                         if (pir.key.userId != userId) {
6121                             // Not the same user, skip it.
6122                             continue;
6123                         }
6124                     } else {
6125                         if (UserHandle.getAppId(pir.uid) != appId) {
6126                             // Different app id, skip it.
6127                             continue;
6128                         }
6129                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6130                             // Different user, skip it.
6131                             continue;
6132                         }
6133                         if (!pir.key.packageName.equals(packageName)) {
6134                             // Different package, skip it.
6135                             continue;
6136                         }
6137                     }
6138                     if (!doit) {
6139                         return true;
6140                     }
6141                     didSomething = true;
6142                     it.remove();
6143                     pir.canceled = true;
6144                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6145                         pir.key.activity.pendingResults.remove(pir.ref);
6146                     }
6147                 }
6148             }
6149         }
6150
6151         if (doit) {
6152             if (purgeCache && packageName != null) {
6153                 AttributeCache ac = AttributeCache.instance();
6154                 if (ac != null) {
6155                     ac.removePackage(packageName);
6156                 }
6157             }
6158             if (mBooted) {
6159                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6160                 mStackSupervisor.scheduleIdleLocked();
6161             }
6162         }
6163
6164         return didSomething;
6165     }
6166
6167     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6168         ProcessRecord old = mProcessNames.remove(name, uid);
6169         if (old != null) {
6170             old.uidRecord.numProcs--;
6171             if (old.uidRecord.numProcs == 0) {
6172                 // No more processes using this uid, tell clients it is gone.
6173                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6174                         "No more processes in " + old.uidRecord);
6175                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6176                 mActiveUids.remove(uid);
6177                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6178             }
6179             old.uidRecord = null;
6180         }
6181         mIsolatedProcesses.remove(uid);
6182         return old;
6183     }
6184
6185     private final void addProcessNameLocked(ProcessRecord proc) {
6186         // We shouldn't already have a process under this name, but just in case we
6187         // need to clean up whatever may be there now.
6188         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6189         if (old == proc && proc.persistent) {
6190             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6191             Slog.w(TAG, "Re-adding persistent process " + proc);
6192         } else if (old != null) {
6193             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6194         }
6195         UidRecord uidRec = mActiveUids.get(proc.uid);
6196         if (uidRec == null) {
6197             uidRec = new UidRecord(proc.uid);
6198             // This is the first appearance of the uid, report it now!
6199             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6200                     "Creating new process uid: " + uidRec);
6201             mActiveUids.put(proc.uid, uidRec);
6202             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6203             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6204         }
6205         proc.uidRecord = uidRec;
6206         uidRec.numProcs++;
6207         mProcessNames.put(proc.processName, proc.uid, proc);
6208         if (proc.isolated) {
6209             mIsolatedProcesses.put(proc.uid, proc);
6210         }
6211     }
6212
6213     boolean removeProcessLocked(ProcessRecord app,
6214             boolean callerWillRestart, boolean allowRestart, String reason) {
6215         final String name = app.processName;
6216         final int uid = app.uid;
6217         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6218             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6219
6220         ProcessRecord old = mProcessNames.get(name, uid);
6221         if (old != app) {
6222             // This process is no longer active, so nothing to do.
6223             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6224             return false;
6225         }
6226         removeProcessNameLocked(name, uid);
6227         if (mHeavyWeightProcess == app) {
6228             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6229                     mHeavyWeightProcess.userId, 0));
6230             mHeavyWeightProcess = null;
6231         }
6232         boolean needRestart = false;
6233         if (app.pid > 0 && app.pid != MY_PID) {
6234             int pid = app.pid;
6235             synchronized (mPidsSelfLocked) {
6236                 mPidsSelfLocked.remove(pid);
6237                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6238             }
6239             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6240             if (app.isolated) {
6241                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6242             }
6243             boolean willRestart = false;
6244             if (app.persistent && !app.isolated) {
6245                 if (!callerWillRestart) {
6246                     willRestart = true;
6247                 } else {
6248                     needRestart = true;
6249                 }
6250             }
6251             app.kill(reason, true);
6252             handleAppDiedLocked(app, willRestart, allowRestart);
6253             if (willRestart) {
6254                 removeLruProcessLocked(app);
6255                 addAppLocked(app.info, false, null /* ABI override */);
6256             }
6257         } else {
6258             mRemovedProcesses.add(app);
6259         }
6260
6261         return needRestart;
6262     }
6263
6264     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6265         cleanupAppInLaunchingProvidersLocked(app, true);
6266         removeProcessLocked(app, false, true, "timeout publishing content providers");
6267     }
6268
6269     private final void processStartTimedOutLocked(ProcessRecord app) {
6270         final int pid = app.pid;
6271         boolean gone = false;
6272         synchronized (mPidsSelfLocked) {
6273             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6274             if (knownApp != null && knownApp.thread == null) {
6275                 mPidsSelfLocked.remove(pid);
6276                 gone = true;
6277             }
6278         }
6279
6280         if (gone) {
6281             Slog.w(TAG, "Process " + app + " failed to attach");
6282             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6283                     pid, app.uid, app.processName);
6284             removeProcessNameLocked(app.processName, app.uid);
6285             if (mHeavyWeightProcess == app) {
6286                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6287                         mHeavyWeightProcess.userId, 0));
6288                 mHeavyWeightProcess = null;
6289             }
6290             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6291             if (app.isolated) {
6292                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6293             }
6294             // Take care of any launching providers waiting for this process.
6295             cleanupAppInLaunchingProvidersLocked(app, true);
6296             // Take care of any services that are waiting for the process.
6297             mServices.processStartTimedOutLocked(app);
6298             app.kill("start timeout", true);
6299             removeLruProcessLocked(app);
6300             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6301                 Slog.w(TAG, "Unattached app died before backup, skipping");
6302                 try {
6303                     IBackupManager bm = IBackupManager.Stub.asInterface(
6304                             ServiceManager.getService(Context.BACKUP_SERVICE));
6305                     bm.agentDisconnected(app.info.packageName);
6306                 } catch (RemoteException e) {
6307                     // Can't happen; the backup manager is local
6308                 }
6309             }
6310             if (isPendingBroadcastProcessLocked(pid)) {
6311                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6312                 skipPendingBroadcastLocked(pid);
6313             }
6314         } else {
6315             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6316         }
6317     }
6318
6319     private final boolean attachApplicationLocked(IApplicationThread thread,
6320             int pid) {
6321
6322         // Find the application record that is being attached...  either via
6323         // the pid if we are running in multiple processes, or just pull the
6324         // next app record if we are emulating process with anonymous threads.
6325         ProcessRecord app;
6326         if (pid != MY_PID && pid >= 0) {
6327             synchronized (mPidsSelfLocked) {
6328                 app = mPidsSelfLocked.get(pid);
6329             }
6330         } else {
6331             app = null;
6332         }
6333
6334         if (app == null) {
6335             Slog.w(TAG, "No pending application record for pid " + pid
6336                     + " (IApplicationThread " + thread + "); dropping process");
6337             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6338             if (pid > 0 && pid != MY_PID) {
6339                 Process.killProcessQuiet(pid);
6340                 //TODO: killProcessGroup(app.info.uid, pid);
6341             } else {
6342                 try {
6343                     thread.scheduleExit();
6344                 } catch (Exception e) {
6345                     // Ignore exceptions.
6346                 }
6347             }
6348             return false;
6349         }
6350
6351         // If this application record is still attached to a previous
6352         // process, clean it up now.
6353         if (app.thread != null) {
6354             handleAppDiedLocked(app, true, true);
6355         }
6356
6357         // Tell the process all about itself.
6358
6359         if (DEBUG_ALL) Slog.v(
6360                 TAG, "Binding process pid " + pid + " to record " + app);
6361
6362         final String processName = app.processName;
6363         try {
6364             AppDeathRecipient adr = new AppDeathRecipient(
6365                     app, pid, thread);
6366             thread.asBinder().linkToDeath(adr, 0);
6367             app.deathRecipient = adr;
6368         } catch (RemoteException e) {
6369             app.resetPackageList(mProcessStats);
6370             startProcessLocked(app, "link fail", processName);
6371             return false;
6372         }
6373
6374         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6375
6376         app.makeActive(thread, mProcessStats);
6377         app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6378         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6379         app.forcingToForeground = null;
6380         updateProcessForegroundLocked(app, false, false);
6381         app.hasShownUi = false;
6382         app.debugging = false;
6383         app.cached = false;
6384         app.killedByAm = false;
6385
6386         // We carefully use the same state that PackageManager uses for
6387         // filtering, since we use this flag to decide if we need to install
6388         // providers when user is unlocked later
6389         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6390
6391         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6392
6393         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6394         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6395
6396         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6397             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6398             msg.obj = app;
6399             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6400         }
6401
6402         if (!normalMode) {
6403             Slog.i(TAG, "Launching preboot mode app: " + app);
6404         }
6405
6406         if (DEBUG_ALL) Slog.v(
6407             TAG, "New app record " + app
6408             + " thread=" + thread.asBinder() + " pid=" + pid);
6409         try {
6410             int testMode = IApplicationThread.DEBUG_OFF;
6411             if (mDebugApp != null && mDebugApp.equals(processName)) {
6412                 testMode = mWaitForDebugger
6413                     ? IApplicationThread.DEBUG_WAIT
6414                     : IApplicationThread.DEBUG_ON;
6415                 app.debugging = true;
6416                 if (mDebugTransient) {
6417                     mDebugApp = mOrigDebugApp;
6418                     mWaitForDebugger = mOrigWaitForDebugger;
6419                 }
6420             }
6421             String profileFile = app.instrumentationProfileFile;
6422             ParcelFileDescriptor profileFd = null;
6423             int samplingInterval = 0;
6424             boolean profileAutoStop = false;
6425             if (mProfileApp != null && mProfileApp.equals(processName)) {
6426                 mProfileProc = app;
6427                 profileFile = mProfileFile;
6428                 profileFd = mProfileFd;
6429                 samplingInterval = mSamplingInterval;
6430                 profileAutoStop = mAutoStopProfiler;
6431             }
6432             boolean enableTrackAllocation = false;
6433             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6434                 enableTrackAllocation = true;
6435                 mTrackAllocationApp = null;
6436             }
6437
6438             // If the app is being launched for restore or full backup, set it up specially
6439             boolean isRestrictedBackupMode = false;
6440             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6441                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6442                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6443                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6444                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6445             }
6446
6447             if (app.instrumentationClass != null) {
6448                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6449                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6450             }
6451             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6452                     + processName + " with config " + mConfiguration);
6453             ApplicationInfo appInfo = app.instrumentationInfo != null
6454                     ? app.instrumentationInfo : app.info;
6455             app.compat = compatibilityInfoForPackageLocked(appInfo);
6456             if (profileFd != null) {
6457                 profileFd = profileFd.dup();
6458             }
6459             ProfilerInfo profilerInfo = profileFile == null ? null
6460                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6461             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6462                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6463                     app.instrumentationUiAutomationConnection, testMode,
6464                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6465                     isRestrictedBackupMode || !normalMode, app.persistent,
6466                     new Configuration(mConfiguration), app.compat,
6467                     getCommonServicesLocked(app.isolated),
6468                     mCoreSettingsObserver.getCoreSettingsLocked());
6469             updateLruProcessLocked(app, false, null);
6470             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6471         } catch (Exception e) {
6472             // todo: Yikes!  What should we do?  For now we will try to
6473             // start another process, but that could easily get us in
6474             // an infinite loop of restarting processes...
6475             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6476
6477             app.resetPackageList(mProcessStats);
6478             app.unlinkDeathRecipient();
6479             startProcessLocked(app, "bind fail", processName);
6480             return false;
6481         }
6482
6483         // Remove this record from the list of starting applications.
6484         mPersistentStartingProcesses.remove(app);
6485         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6486                 "Attach application locked removing on hold: " + app);
6487         mProcessesOnHold.remove(app);
6488
6489         boolean badApp = false;
6490         boolean didSomething = false;
6491
6492         // See if the top visible activity is waiting to run in this process...
6493         if (normalMode) {
6494             try {
6495                 if (mStackSupervisor.attachApplicationLocked(app)) {
6496                     didSomething = true;
6497                 }
6498             } catch (Exception e) {
6499                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6500                 badApp = true;
6501             }
6502         }
6503
6504         // Find any services that should be running in this process...
6505         if (!badApp) {
6506             try {
6507                 didSomething |= mServices.attachApplicationLocked(app, processName);
6508             } catch (Exception e) {
6509                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6510                 badApp = true;
6511             }
6512         }
6513
6514         // Check if a next-broadcast receiver is in this process...
6515         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6516             try {
6517                 didSomething |= sendPendingBroadcastsLocked(app);
6518             } catch (Exception e) {
6519                 // If the app died trying to launch the receiver we declare it 'bad'
6520                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6521                 badApp = true;
6522             }
6523         }
6524
6525         // Check whether the next backup agent is in this process...
6526         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6527             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6528                     "New app is backup target, launching agent for " + app);
6529             notifyPackageUse(mBackupTarget.appInfo.packageName,
6530                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6531             try {
6532                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6533                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6534                         mBackupTarget.backupMode);
6535             } catch (Exception e) {
6536                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6537                 badApp = true;
6538             }
6539         }
6540
6541         if (badApp) {
6542             app.kill("error during init", true);
6543             handleAppDiedLocked(app, false, true);
6544             return false;
6545         }
6546
6547         if (!didSomething) {
6548             updateOomAdjLocked();
6549         }
6550
6551         return true;
6552     }
6553
6554     @Override
6555     public final void attachApplication(IApplicationThread thread) {
6556         synchronized (this) {
6557             int callingPid = Binder.getCallingPid();
6558             final long origId = Binder.clearCallingIdentity();
6559             attachApplicationLocked(thread, callingPid);
6560             Binder.restoreCallingIdentity(origId);
6561         }
6562     }
6563
6564     @Override
6565     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6566         final long origId = Binder.clearCallingIdentity();
6567         synchronized (this) {
6568             ActivityStack stack = ActivityRecord.getStackLocked(token);
6569             if (stack != null) {
6570                 ActivityRecord r =
6571                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6572                 if (stopProfiling) {
6573                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6574                         try {
6575                             mProfileFd.close();
6576                         } catch (IOException e) {
6577                         }
6578                         clearProfilerLocked();
6579                     }
6580                 }
6581             }
6582         }
6583         Binder.restoreCallingIdentity(origId);
6584     }
6585
6586     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6587         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6588                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6589     }
6590
6591     void enableScreenAfterBoot() {
6592         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6593                 SystemClock.uptimeMillis());
6594         mWindowManager.enableScreenAfterBoot();
6595
6596         synchronized (this) {
6597             updateEventDispatchingLocked();
6598         }
6599     }
6600
6601     @Override
6602     public void showBootMessage(final CharSequence msg, final boolean always) {
6603         if (Binder.getCallingUid() != Process.myUid()) {
6604             // These days only the core system can call this, so apps can't get in
6605             // the way of what we show about running them.
6606         }
6607         mWindowManager.showBootMessage(msg, always);
6608     }
6609
6610     @Override
6611     public void keyguardWaitingForActivityDrawn() {
6612         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6613         final long token = Binder.clearCallingIdentity();
6614         try {
6615             synchronized (this) {
6616                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6617                 mWindowManager.keyguardWaitingForActivityDrawn();
6618                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6619                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6620                     updateSleepIfNeededLocked();
6621                 }
6622             }
6623         } finally {
6624             Binder.restoreCallingIdentity(token);
6625         }
6626     }
6627
6628     @Override
6629     public void keyguardGoingAway(int flags) {
6630         enforceNotIsolatedCaller("keyguardGoingAway");
6631         final long token = Binder.clearCallingIdentity();
6632         try {
6633             synchronized (this) {
6634                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6635                 mWindowManager.keyguardGoingAway(flags);
6636                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6637                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6638                     updateSleepIfNeededLocked();
6639
6640                     // Some stack visibility might change (e.g. docked stack)
6641                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6642                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6643                 }
6644             }
6645         } finally {
6646             Binder.restoreCallingIdentity(token);
6647         }
6648     }
6649
6650     final void finishBooting() {
6651         synchronized (this) {
6652             if (!mBootAnimationComplete) {
6653                 mCallFinishBooting = true;
6654                 return;
6655             }
6656             mCallFinishBooting = false;
6657         }
6658
6659         ArraySet<String> completedIsas = new ArraySet<String>();
6660         for (String abi : Build.SUPPORTED_ABIS) {
6661             Process.establishZygoteConnectionForAbi(abi);
6662             final String instructionSet = VMRuntime.getInstructionSet(abi);
6663             if (!completedIsas.contains(instructionSet)) {
6664                 try {
6665                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6666                 } catch (InstallerException e) {
6667                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6668                             e.getMessage() +")");
6669                 }
6670                 completedIsas.add(instructionSet);
6671             }
6672         }
6673
6674         IntentFilter pkgFilter = new IntentFilter();
6675         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6676         pkgFilter.addDataScheme("package");
6677         mContext.registerReceiver(new BroadcastReceiver() {
6678             @Override
6679             public void onReceive(Context context, Intent intent) {
6680                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6681                 if (pkgs != null) {
6682                     for (String pkg : pkgs) {
6683                         synchronized (ActivityManagerService.this) {
6684                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6685                                     0, "query restart")) {
6686                                 setResultCode(Activity.RESULT_OK);
6687                                 return;
6688                             }
6689                         }
6690                     }
6691                 }
6692             }
6693         }, pkgFilter);
6694
6695         IntentFilter dumpheapFilter = new IntentFilter();
6696         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6697         mContext.registerReceiver(new BroadcastReceiver() {
6698             @Override
6699             public void onReceive(Context context, Intent intent) {
6700                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6701                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6702                 } else {
6703                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6704                 }
6705             }
6706         }, dumpheapFilter);
6707
6708         // Let system services know.
6709         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6710
6711         synchronized (this) {
6712             // Ensure that any processes we had put on hold are now started
6713             // up.
6714             final int NP = mProcessesOnHold.size();
6715             if (NP > 0) {
6716                 ArrayList<ProcessRecord> procs =
6717                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6718                 for (int ip=0; ip<NP; ip++) {
6719                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6720                             + procs.get(ip));
6721                     startProcessLocked(procs.get(ip), "on-hold", null);
6722                 }
6723             }
6724
6725             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6726                 // Start looking for apps that are abusing wake locks.
6727                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6729                 // Tell anyone interested that we are done booting!
6730                 SystemProperties.set("sys.boot_completed", "1");
6731
6732                 // And trigger dev.bootcomplete if we are not showing encryption progress
6733                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6734                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6735                     SystemProperties.set("dev.bootcomplete", "1");
6736                 }
6737                 mUserController.sendBootCompletedLocked(
6738                         new IIntentReceiver.Stub() {
6739                             @Override
6740                             public void performReceive(Intent intent, int resultCode,
6741                                     String data, Bundle extras, boolean ordered,
6742                                     boolean sticky, int sendingUser) {
6743                                 synchronized (ActivityManagerService.this) {
6744                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6745                                             true, false);
6746                                 }
6747                             }
6748                         });
6749                 scheduleStartProfilesLocked();
6750             }
6751         }
6752     }
6753
6754     @Override
6755     public void bootAnimationComplete() {
6756         final boolean callFinishBooting;
6757         synchronized (this) {
6758             callFinishBooting = mCallFinishBooting;
6759             mBootAnimationComplete = true;
6760         }
6761         if (callFinishBooting) {
6762             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6763             finishBooting();
6764             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6765         }
6766     }
6767
6768     final void ensureBootCompleted() {
6769         boolean booting;
6770         boolean enableScreen;
6771         synchronized (this) {
6772             booting = mBooting;
6773             mBooting = false;
6774             enableScreen = !mBooted;
6775             mBooted = true;
6776         }
6777
6778         if (booting) {
6779             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6780             finishBooting();
6781             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6782         }
6783
6784         if (enableScreen) {
6785             enableScreenAfterBoot();
6786         }
6787     }
6788
6789     @Override
6790     public final void activityResumed(IBinder token) {
6791         final long origId = Binder.clearCallingIdentity();
6792         synchronized(this) {
6793             ActivityStack stack = ActivityRecord.getStackLocked(token);
6794             if (stack != null) {
6795                 stack.activityResumedLocked(token);
6796             }
6797         }
6798         Binder.restoreCallingIdentity(origId);
6799     }
6800
6801     @Override
6802     public final void activityPaused(IBinder token) {
6803         final long origId = Binder.clearCallingIdentity();
6804         synchronized(this) {
6805             ActivityStack stack = ActivityRecord.getStackLocked(token);
6806             if (stack != null) {
6807                 stack.activityPausedLocked(token, false);
6808             }
6809         }
6810         Binder.restoreCallingIdentity(origId);
6811     }
6812
6813     @Override
6814     public final void activityStopped(IBinder token, Bundle icicle,
6815             PersistableBundle persistentState, CharSequence description) {
6816         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6817
6818         // Refuse possible leaked file descriptors
6819         if (icicle != null && icicle.hasFileDescriptors()) {
6820             throw new IllegalArgumentException("File descriptors passed in Bundle");
6821         }
6822
6823         final long origId = Binder.clearCallingIdentity();
6824
6825         synchronized (this) {
6826             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6827             if (r != null) {
6828                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6829             }
6830         }
6831
6832         trimApplications();
6833
6834         Binder.restoreCallingIdentity(origId);
6835     }
6836
6837     @Override
6838     public final void activityDestroyed(IBinder token) {
6839         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6840         synchronized (this) {
6841             ActivityStack stack = ActivityRecord.getStackLocked(token);
6842             if (stack != null) {
6843                 stack.activityDestroyedLocked(token, "activityDestroyed");
6844             }
6845         }
6846     }
6847
6848     @Override
6849     public final void activityRelaunched(IBinder token) {
6850         final long origId = Binder.clearCallingIdentity();
6851         synchronized (this) {
6852             mStackSupervisor.activityRelaunchedLocked(token);
6853         }
6854         Binder.restoreCallingIdentity(origId);
6855     }
6856
6857     @Override
6858     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6859             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6860         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6861                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6862         synchronized (this) {
6863             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6864             if (record == null) {
6865                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6866                         + "found for: " + token);
6867             }
6868             record.setSizeConfigurations(horizontalSizeConfiguration,
6869                     verticalSizeConfigurations, smallestSizeConfigurations);
6870         }
6871     }
6872
6873     @Override
6874     public final void backgroundResourcesReleased(IBinder token) {
6875         final long origId = Binder.clearCallingIdentity();
6876         try {
6877             synchronized (this) {
6878                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6879                 if (stack != null) {
6880                     stack.backgroundResourcesReleased();
6881                 }
6882             }
6883         } finally {
6884             Binder.restoreCallingIdentity(origId);
6885         }
6886     }
6887
6888     @Override
6889     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6890         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6891     }
6892
6893     @Override
6894     public final void notifyEnterAnimationComplete(IBinder token) {
6895         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6896     }
6897
6898     @Override
6899     public String getCallingPackage(IBinder token) {
6900         synchronized (this) {
6901             ActivityRecord r = getCallingRecordLocked(token);
6902             return r != null ? r.info.packageName : null;
6903         }
6904     }
6905
6906     @Override
6907     public ComponentName getCallingActivity(IBinder token) {
6908         synchronized (this) {
6909             ActivityRecord r = getCallingRecordLocked(token);
6910             return r != null ? r.intent.getComponent() : null;
6911         }
6912     }
6913
6914     private ActivityRecord getCallingRecordLocked(IBinder token) {
6915         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6916         if (r == null) {
6917             return null;
6918         }
6919         return r.resultTo;
6920     }
6921
6922     @Override
6923     public ComponentName getActivityClassForToken(IBinder token) {
6924         synchronized(this) {
6925             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926             if (r == null) {
6927                 return null;
6928             }
6929             return r.intent.getComponent();
6930         }
6931     }
6932
6933     @Override
6934     public String getPackageForToken(IBinder token) {
6935         synchronized(this) {
6936             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6937             if (r == null) {
6938                 return null;
6939             }
6940             return r.packageName;
6941         }
6942     }
6943
6944     @Override
6945     public boolean isRootVoiceInteraction(IBinder token) {
6946         synchronized(this) {
6947             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6948             if (r == null) {
6949                 return false;
6950             }
6951             return r.rootVoiceInteraction;
6952         }
6953     }
6954
6955     @Override
6956     public IIntentSender getIntentSender(int type,
6957             String packageName, IBinder token, String resultWho,
6958             int requestCode, Intent[] intents, String[] resolvedTypes,
6959             int flags, Bundle bOptions, int userId) {
6960         enforceNotIsolatedCaller("getIntentSender");
6961         // Refuse possible leaked file descriptors
6962         if (intents != null) {
6963             if (intents.length < 1) {
6964                 throw new IllegalArgumentException("Intents array length must be >= 1");
6965             }
6966             for (int i=0; i<intents.length; i++) {
6967                 Intent intent = intents[i];
6968                 if (intent != null) {
6969                     if (intent.hasFileDescriptors()) {
6970                         throw new IllegalArgumentException("File descriptors passed in Intent");
6971                     }
6972                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6973                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6974                         throw new IllegalArgumentException(
6975                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6976                     }
6977                     intents[i] = new Intent(intent);
6978                 }
6979             }
6980             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6981                 throw new IllegalArgumentException(
6982                         "Intent array length does not match resolvedTypes length");
6983             }
6984         }
6985         if (bOptions != null) {
6986             if (bOptions.hasFileDescriptors()) {
6987                 throw new IllegalArgumentException("File descriptors passed in options");
6988             }
6989         }
6990
6991         synchronized(this) {
6992             int callingUid = Binder.getCallingUid();
6993             int origUserId = userId;
6994             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6995                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6996                     ALLOW_NON_FULL, "getIntentSender", null);
6997             if (origUserId == UserHandle.USER_CURRENT) {
6998                 // We don't want to evaluate this until the pending intent is
6999                 // actually executed.  However, we do want to always do the
7000                 // security checking for it above.
7001                 userId = UserHandle.USER_CURRENT;
7002             }
7003             try {
7004                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7005                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7006                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7007                     if (!UserHandle.isSameApp(callingUid, uid)) {
7008                         String msg = "Permission Denial: getIntentSender() from pid="
7009                             + Binder.getCallingPid()
7010                             + ", uid=" + Binder.getCallingUid()
7011                             + ", (need uid=" + uid + ")"
7012                             + " is not allowed to send as package " + packageName;
7013                         Slog.w(TAG, msg);
7014                         throw new SecurityException(msg);
7015                     }
7016                 }
7017
7018                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7019                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7020
7021             } catch (RemoteException e) {
7022                 throw new SecurityException(e);
7023             }
7024         }
7025     }
7026
7027     IIntentSender getIntentSenderLocked(int type, String packageName,
7028             int callingUid, int userId, IBinder token, String resultWho,
7029             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7030             Bundle bOptions) {
7031         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7032         ActivityRecord activity = null;
7033         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7034             activity = ActivityRecord.isInStackLocked(token);
7035             if (activity == null) {
7036                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7037                 return null;
7038             }
7039             if (activity.finishing) {
7040                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7041                 return null;
7042             }
7043         }
7044
7045         // We're going to be splicing together extras before sending, so we're
7046         // okay poking into any contained extras.
7047         if (intents != null) {
7048             for (int i = 0; i < intents.length; i++) {
7049                 intents[i].setDefusable(true);
7050             }
7051         }
7052         Bundle.setDefusable(bOptions, true);
7053
7054         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7055         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7056         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7057         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7058                 |PendingIntent.FLAG_UPDATE_CURRENT);
7059
7060         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7061                 type, packageName, activity, resultWho,
7062                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7063         WeakReference<PendingIntentRecord> ref;
7064         ref = mIntentSenderRecords.get(key);
7065         PendingIntentRecord rec = ref != null ? ref.get() : null;
7066         if (rec != null) {
7067             if (!cancelCurrent) {
7068                 if (updateCurrent) {
7069                     if (rec.key.requestIntent != null) {
7070                         rec.key.requestIntent.replaceExtras(intents != null ?
7071                                 intents[intents.length - 1] : null);
7072                     }
7073                     if (intents != null) {
7074                         intents[intents.length-1] = rec.key.requestIntent;
7075                         rec.key.allIntents = intents;
7076                         rec.key.allResolvedTypes = resolvedTypes;
7077                     } else {
7078                         rec.key.allIntents = null;
7079                         rec.key.allResolvedTypes = null;
7080                     }
7081                 }
7082                 return rec;
7083             }
7084             rec.canceled = true;
7085             mIntentSenderRecords.remove(key);
7086         }
7087         if (noCreate) {
7088             return rec;
7089         }
7090         rec = new PendingIntentRecord(this, key, callingUid);
7091         mIntentSenderRecords.put(key, rec.ref);
7092         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7093             if (activity.pendingResults == null) {
7094                 activity.pendingResults
7095                         = new HashSet<WeakReference<PendingIntentRecord>>();
7096             }
7097             activity.pendingResults.add(rec.ref);
7098         }
7099         return rec;
7100     }
7101
7102     @Override
7103     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7104             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7105         if (target instanceof PendingIntentRecord) {
7106             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7107                     finishedReceiver, requiredPermission, options);
7108         } else {
7109             if (intent == null) {
7110                 // Weird case: someone has given us their own custom IIntentSender, and now
7111                 // they have someone else trying to send to it but of course this isn't
7112                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7113                 // supplying an Intent... but we never want to dispatch a null Intent to
7114                 // a receiver, so um...  let's make something up.
7115                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7116                 intent = new Intent(Intent.ACTION_MAIN);
7117             }
7118             try {
7119                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7120             } catch (RemoteException e) {
7121             }
7122             // Platform code can rely on getting a result back when the send is done, but if
7123             // this intent sender is from outside of the system we can't rely on it doing that.
7124             // So instead we don't give it the result receiver, and instead just directly
7125             // report the finish immediately.
7126             if (finishedReceiver != null) {
7127                 try {
7128                     finishedReceiver.performReceive(intent, 0,
7129                             null, null, false, false, UserHandle.getCallingUserId());
7130                 } catch (RemoteException e) {
7131                 }
7132             }
7133             return 0;
7134         }
7135     }
7136
7137     @Override
7138     public void cancelIntentSender(IIntentSender sender) {
7139         if (!(sender instanceof PendingIntentRecord)) {
7140             return;
7141         }
7142         synchronized(this) {
7143             PendingIntentRecord rec = (PendingIntentRecord)sender;
7144             try {
7145                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7146                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7147                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7148                     String msg = "Permission Denial: cancelIntentSender() from pid="
7149                         + Binder.getCallingPid()
7150                         + ", uid=" + Binder.getCallingUid()
7151                         + " is not allowed to cancel packges "
7152                         + rec.key.packageName;
7153                     Slog.w(TAG, msg);
7154                     throw new SecurityException(msg);
7155                 }
7156             } catch (RemoteException e) {
7157                 throw new SecurityException(e);
7158             }
7159             cancelIntentSenderLocked(rec, true);
7160         }
7161     }
7162
7163     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7164         rec.canceled = true;
7165         mIntentSenderRecords.remove(rec.key);
7166         if (cleanActivity && rec.key.activity != null) {
7167             rec.key.activity.pendingResults.remove(rec.ref);
7168         }
7169     }
7170
7171     @Override
7172     public String getPackageForIntentSender(IIntentSender pendingResult) {
7173         if (!(pendingResult instanceof PendingIntentRecord)) {
7174             return null;
7175         }
7176         try {
7177             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7178             return res.key.packageName;
7179         } catch (ClassCastException e) {
7180         }
7181         return null;
7182     }
7183
7184     @Override
7185     public int getUidForIntentSender(IIntentSender sender) {
7186         if (sender instanceof PendingIntentRecord) {
7187             try {
7188                 PendingIntentRecord res = (PendingIntentRecord)sender;
7189                 return res.uid;
7190             } catch (ClassCastException e) {
7191             }
7192         }
7193         return -1;
7194     }
7195
7196     @Override
7197     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7198         if (!(pendingResult instanceof PendingIntentRecord)) {
7199             return false;
7200         }
7201         try {
7202             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7203             if (res.key.allIntents == null) {
7204                 return false;
7205             }
7206             for (int i=0; i<res.key.allIntents.length; i++) {
7207                 Intent intent = res.key.allIntents[i];
7208                 if (intent.getPackage() != null && intent.getComponent() != null) {
7209                     return false;
7210                 }
7211             }
7212             return true;
7213         } catch (ClassCastException e) {
7214         }
7215         return false;
7216     }
7217
7218     @Override
7219     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7220         if (!(pendingResult instanceof PendingIntentRecord)) {
7221             return false;
7222         }
7223         try {
7224             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7225             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7226                 return true;
7227             }
7228             return false;
7229         } catch (ClassCastException e) {
7230         }
7231         return false;
7232     }
7233
7234     @Override
7235     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7236         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7237                 "getIntentForIntentSender()");
7238         if (!(pendingResult instanceof PendingIntentRecord)) {
7239             return null;
7240         }
7241         try {
7242             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7243             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7244         } catch (ClassCastException e) {
7245         }
7246         return null;
7247     }
7248
7249     @Override
7250     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7251         if (!(pendingResult instanceof PendingIntentRecord)) {
7252             return null;
7253         }
7254         try {
7255             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7256             synchronized (this) {
7257                 return getTagForIntentSenderLocked(res, prefix);
7258             }
7259         } catch (ClassCastException e) {
7260         }
7261         return null;
7262     }
7263
7264     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7265         final Intent intent = res.key.requestIntent;
7266         if (intent != null) {
7267             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7268                     || res.lastTagPrefix.equals(prefix))) {
7269                 return res.lastTag;
7270             }
7271             res.lastTagPrefix = prefix;
7272             final StringBuilder sb = new StringBuilder(128);
7273             if (prefix != null) {
7274                 sb.append(prefix);
7275             }
7276             if (intent.getAction() != null) {
7277                 sb.append(intent.getAction());
7278             } else if (intent.getComponent() != null) {
7279                 intent.getComponent().appendShortString(sb);
7280             } else {
7281                 sb.append("?");
7282             }
7283             return res.lastTag = sb.toString();
7284         }
7285         return null;
7286     }
7287
7288     @Override
7289     public void setProcessLimit(int max) {
7290         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7291                 "setProcessLimit()");
7292         synchronized (this) {
7293             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7294             mProcessLimitOverride = max;
7295         }
7296         trimApplications();
7297     }
7298
7299     @Override
7300     public int getProcessLimit() {
7301         synchronized (this) {
7302             return mProcessLimitOverride;
7303         }
7304     }
7305
7306     void foregroundTokenDied(ForegroundToken token) {
7307         synchronized (ActivityManagerService.this) {
7308             synchronized (mPidsSelfLocked) {
7309                 ForegroundToken cur
7310                     = mForegroundProcesses.get(token.pid);
7311                 if (cur != token) {
7312                     return;
7313                 }
7314                 mForegroundProcesses.remove(token.pid);
7315                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7316                 if (pr == null) {
7317                     return;
7318                 }
7319                 pr.forcingToForeground = null;
7320                 updateProcessForegroundLocked(pr, false, false);
7321             }
7322             updateOomAdjLocked();
7323         }
7324     }
7325
7326     @Override
7327     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7328         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329                 "setProcessForeground()");
7330         synchronized(this) {
7331             boolean changed = false;
7332
7333             synchronized (mPidsSelfLocked) {
7334                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7335                 if (pr == null && isForeground) {
7336                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7337                     return;
7338                 }
7339                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7340                 if (oldToken != null) {
7341                     oldToken.token.unlinkToDeath(oldToken, 0);
7342                     mForegroundProcesses.remove(pid);
7343                     if (pr != null) {
7344                         pr.forcingToForeground = null;
7345                     }
7346                     changed = true;
7347                 }
7348                 if (isForeground && token != null) {
7349                     ForegroundToken newToken = new ForegroundToken() {
7350                         @Override
7351                         public void binderDied() {
7352                             foregroundTokenDied(this);
7353                         }
7354                     };
7355                     newToken.pid = pid;
7356                     newToken.token = token;
7357                     try {
7358                         token.linkToDeath(newToken, 0);
7359                         mForegroundProcesses.put(pid, newToken);
7360                         pr.forcingToForeground = token;
7361                         changed = true;
7362                     } catch (RemoteException e) {
7363                         // If the process died while doing this, we will later
7364                         // do the cleanup with the process death link.
7365                     }
7366                 }
7367             }
7368
7369             if (changed) {
7370                 updateOomAdjLocked();
7371             }
7372         }
7373     }
7374
7375     @Override
7376     public boolean isAppForeground(int uid) throws RemoteException {
7377         synchronized (this) {
7378             UidRecord uidRec = mActiveUids.get(uid);
7379             if (uidRec == null || uidRec.idle) {
7380                 return false;
7381             }
7382             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7383         }
7384     }
7385
7386     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7387     // be guarded by permission checking.
7388     int getUidState(int uid) {
7389         synchronized (this) {
7390             UidRecord uidRec = mActiveUids.get(uid);
7391             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7392         }
7393     }
7394
7395     @Override
7396     public boolean isInMultiWindowMode(IBinder token) {
7397         final long origId = Binder.clearCallingIdentity();
7398         try {
7399             synchronized(this) {
7400                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7401                 if (r == null) {
7402                     return false;
7403                 }
7404                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7405                 return !r.task.mFullscreen;
7406             }
7407         } finally {
7408             Binder.restoreCallingIdentity(origId);
7409         }
7410     }
7411
7412     @Override
7413     public boolean isInPictureInPictureMode(IBinder token) {
7414         final long origId = Binder.clearCallingIdentity();
7415         try {
7416             synchronized(this) {
7417                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7418                 if (stack == null) {
7419                     return false;
7420                 }
7421                 return stack.mStackId == PINNED_STACK_ID;
7422             }
7423         } finally {
7424             Binder.restoreCallingIdentity(origId);
7425         }
7426     }
7427
7428     @Override
7429     public void enterPictureInPictureMode(IBinder token) {
7430         final long origId = Binder.clearCallingIdentity();
7431         try {
7432             synchronized(this) {
7433                 if (!mSupportsPictureInPicture) {
7434                     throw new IllegalStateException("enterPictureInPictureMode: "
7435                             + "Device doesn't support picture-in-picture mode.");
7436                 }
7437
7438                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7439
7440                 if (r == null) {
7441                     throw new IllegalStateException("enterPictureInPictureMode: "
7442                             + "Can't find activity for token=" + token);
7443                 }
7444
7445                 if (!r.supportsPictureInPicture()) {
7446                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7447                             + "Picture-In-Picture not supported for r=" + r);
7448                 }
7449
7450                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7451                 // current bounds.
7452                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7453                 final Rect bounds = (pinnedStack != null)
7454                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7455
7456                 mStackSupervisor.moveActivityToPinnedStackLocked(
7457                         r, "enterPictureInPictureMode", bounds);
7458             }
7459         } finally {
7460             Binder.restoreCallingIdentity(origId);
7461         }
7462     }
7463
7464     // =========================================================
7465     // PROCESS INFO
7466     // =========================================================
7467
7468     static class ProcessInfoService extends IProcessInfoService.Stub {
7469         final ActivityManagerService mActivityManagerService;
7470         ProcessInfoService(ActivityManagerService activityManagerService) {
7471             mActivityManagerService = activityManagerService;
7472         }
7473
7474         @Override
7475         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7476             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7477                     /*in*/ pids, /*out*/ states, null);
7478         }
7479
7480         @Override
7481         public void getProcessStatesAndOomScoresFromPids(
7482                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7483             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7484                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7485         }
7486     }
7487
7488     /**
7489      * For each PID in the given input array, write the current process state
7490      * for that process into the states array, or -1 to indicate that no
7491      * process with the given PID exists. If scores array is provided, write
7492      * the oom score for the process into the scores array, with INVALID_ADJ
7493      * indicating the PID doesn't exist.
7494      */
7495     public void getProcessStatesAndOomScoresForPIDs(
7496             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7497         if (scores != null) {
7498             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7499                     "getProcessStatesAndOomScoresForPIDs()");
7500         }
7501
7502         if (pids == null) {
7503             throw new NullPointerException("pids");
7504         } else if (states == null) {
7505             throw new NullPointerException("states");
7506         } else if (pids.length != states.length) {
7507             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7508         } else if (scores != null && pids.length != scores.length) {
7509             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7510         }
7511
7512         synchronized (mPidsSelfLocked) {
7513             for (int i = 0; i < pids.length; i++) {
7514                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7515                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7516                         pr.curProcState;
7517                 if (scores != null) {
7518                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7519                 }
7520             }
7521         }
7522     }
7523
7524     // =========================================================
7525     // PERMISSIONS
7526     // =========================================================
7527
7528     static class PermissionController extends IPermissionController.Stub {
7529         ActivityManagerService mActivityManagerService;
7530         PermissionController(ActivityManagerService activityManagerService) {
7531             mActivityManagerService = activityManagerService;
7532         }
7533
7534         @Override
7535         public boolean checkPermission(String permission, int pid, int uid) {
7536             return mActivityManagerService.checkPermission(permission, pid,
7537                     uid) == PackageManager.PERMISSION_GRANTED;
7538         }
7539
7540         @Override
7541         public String[] getPackagesForUid(int uid) {
7542             return mActivityManagerService.mContext.getPackageManager()
7543                     .getPackagesForUid(uid);
7544         }
7545
7546         @Override
7547         public boolean isRuntimePermission(String permission) {
7548             try {
7549                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7550                         .getPermissionInfo(permission, 0);
7551                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7552             } catch (NameNotFoundException nnfe) {
7553                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7554             }
7555             return false;
7556         }
7557     }
7558
7559     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7560         @Override
7561         public int checkComponentPermission(String permission, int pid, int uid,
7562                 int owningUid, boolean exported) {
7563             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7564                     owningUid, exported);
7565         }
7566
7567         @Override
7568         public Object getAMSLock() {
7569             return ActivityManagerService.this;
7570         }
7571     }
7572
7573     /**
7574      * This can be called with or without the global lock held.
7575      */
7576     int checkComponentPermission(String permission, int pid, int uid,
7577             int owningUid, boolean exported) {
7578         if (pid == MY_PID) {
7579             return PackageManager.PERMISSION_GRANTED;
7580         }
7581         return ActivityManager.checkComponentPermission(permission, uid,
7582                 owningUid, exported);
7583     }
7584
7585     /**
7586      * As the only public entry point for permissions checking, this method
7587      * can enforce the semantic that requesting a check on a null global
7588      * permission is automatically denied.  (Internally a null permission
7589      * string is used when calling {@link #checkComponentPermission} in cases
7590      * when only uid-based security is needed.)
7591      *
7592      * This can be called with or without the global lock held.
7593      */
7594     @Override
7595     public int checkPermission(String permission, int pid, int uid) {
7596         if (permission == null) {
7597             return PackageManager.PERMISSION_DENIED;
7598         }
7599         return checkComponentPermission(permission, pid, uid, -1, true);
7600     }
7601
7602     @Override
7603     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7604         if (permission == null) {
7605             return PackageManager.PERMISSION_DENIED;
7606         }
7607
7608         // We might be performing an operation on behalf of an indirect binder
7609         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7610         // client identity accordingly before proceeding.
7611         Identity tlsIdentity = sCallerIdentity.get();
7612         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7613             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7614                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7615             uid = tlsIdentity.uid;
7616             pid = tlsIdentity.pid;
7617         }
7618
7619         return checkComponentPermission(permission, pid, uid, -1, true);
7620     }
7621
7622     /**
7623      * Binder IPC calls go through the public entry point.
7624      * This can be called with or without the global lock held.
7625      */
7626     int checkCallingPermission(String permission) {
7627         return checkPermission(permission,
7628                 Binder.getCallingPid(),
7629                 UserHandle.getAppId(Binder.getCallingUid()));
7630     }
7631
7632     /**
7633      * This can be called with or without the global lock held.
7634      */
7635     void enforceCallingPermission(String permission, String func) {
7636         if (checkCallingPermission(permission)
7637                 == PackageManager.PERMISSION_GRANTED) {
7638             return;
7639         }
7640
7641         String msg = "Permission Denial: " + func + " from pid="
7642                 + Binder.getCallingPid()
7643                 + ", uid=" + Binder.getCallingUid()
7644                 + " requires " + permission;
7645         Slog.w(TAG, msg);
7646         throw new SecurityException(msg);
7647     }
7648
7649     /**
7650      * Determine if UID is holding permissions required to access {@link Uri} in
7651      * the given {@link ProviderInfo}. Final permission checking is always done
7652      * in {@link ContentProvider}.
7653      */
7654     private final boolean checkHoldingPermissionsLocked(
7655             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7656         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7657                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7658         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7659             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7660                     != PERMISSION_GRANTED) {
7661                 return false;
7662             }
7663         }
7664         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7665     }
7666
7667     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7668             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7669         if (pi.applicationInfo.uid == uid) {
7670             return true;
7671         } else if (!pi.exported) {
7672             return false;
7673         }
7674
7675         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7676         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7677         try {
7678             // check if target holds top-level <provider> permissions
7679             if (!readMet && pi.readPermission != null && considerUidPermissions
7680                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7681                 readMet = true;
7682             }
7683             if (!writeMet && pi.writePermission != null && considerUidPermissions
7684                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7685                 writeMet = true;
7686             }
7687
7688             // track if unprotected read/write is allowed; any denied
7689             // <path-permission> below removes this ability
7690             boolean allowDefaultRead = pi.readPermission == null;
7691             boolean allowDefaultWrite = pi.writePermission == null;
7692
7693             // check if target holds any <path-permission> that match uri
7694             final PathPermission[] pps = pi.pathPermissions;
7695             if (pps != null) {
7696                 final String path = grantUri.uri.getPath();
7697                 int i = pps.length;
7698                 while (i > 0 && (!readMet || !writeMet)) {
7699                     i--;
7700                     PathPermission pp = pps[i];
7701                     if (pp.match(path)) {
7702                         if (!readMet) {
7703                             final String pprperm = pp.getReadPermission();
7704                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7705                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7706                                     + ": match=" + pp.match(path)
7707                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7708                             if (pprperm != null) {
7709                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7710                                         == PERMISSION_GRANTED) {
7711                                     readMet = true;
7712                                 } else {
7713                                     allowDefaultRead = false;
7714                                 }
7715                             }
7716                         }
7717                         if (!writeMet) {
7718                             final String ppwperm = pp.getWritePermission();
7719                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7720                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7721                                     + ": match=" + pp.match(path)
7722                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7723                             if (ppwperm != null) {
7724                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7725                                         == PERMISSION_GRANTED) {
7726                                     writeMet = true;
7727                                 } else {
7728                                     allowDefaultWrite = false;
7729                                 }
7730                             }
7731                         }
7732                     }
7733                 }
7734             }
7735
7736             // grant unprotected <provider> read/write, if not blocked by
7737             // <path-permission> above
7738             if (allowDefaultRead) readMet = true;
7739             if (allowDefaultWrite) writeMet = true;
7740
7741         } catch (RemoteException e) {
7742             return false;
7743         }
7744
7745         return readMet && writeMet;
7746     }
7747
7748     public int getAppStartMode(int uid, String packageName) {
7749         synchronized (this) {
7750             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7751         }
7752     }
7753
7754     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7755             boolean allowWhenForeground) {
7756         UidRecord uidRec = mActiveUids.get(uid);
7757         if (!mLenientBackgroundCheck) {
7758             if (!allowWhenForeground || uidRec == null
7759                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7760                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7761                         packageName) != AppOpsManager.MODE_ALLOWED) {
7762                     return ActivityManager.APP_START_MODE_DELAYED;
7763                 }
7764             }
7765
7766         } else if (uidRec == null || uidRec.idle) {
7767             if (callingPid >= 0) {
7768                 ProcessRecord proc;
7769                 synchronized (mPidsSelfLocked) {
7770                     proc = mPidsSelfLocked.get(callingPid);
7771                 }
7772                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7773                     // Whoever is instigating this is in the foreground, so we will allow it
7774                     // to go through.
7775                     return ActivityManager.APP_START_MODE_NORMAL;
7776                 }
7777             }
7778             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7779                     != AppOpsManager.MODE_ALLOWED) {
7780                 return ActivityManager.APP_START_MODE_DELAYED;
7781             }
7782         }
7783         return ActivityManager.APP_START_MODE_NORMAL;
7784     }
7785
7786     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7787         ProviderInfo pi = null;
7788         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7789         if (cpr != null) {
7790             pi = cpr.info;
7791         } else {
7792             try {
7793                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7794                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7795             } catch (RemoteException ex) {
7796             }
7797         }
7798         return pi;
7799     }
7800
7801     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7802         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7803         if (targetUris != null) {
7804             return targetUris.get(grantUri);
7805         }
7806         return null;
7807     }
7808
7809     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7810             String targetPkg, int targetUid, GrantUri grantUri) {
7811         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7812         if (targetUris == null) {
7813             targetUris = Maps.newArrayMap();
7814             mGrantedUriPermissions.put(targetUid, targetUris);
7815         }
7816
7817         UriPermission perm = targetUris.get(grantUri);
7818         if (perm == null) {
7819             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7820             targetUris.put(grantUri, perm);
7821         }
7822
7823         return perm;
7824     }
7825
7826     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7827             final int modeFlags) {
7828         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7829         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7830                 : UriPermission.STRENGTH_OWNED;
7831
7832         // Root gets to do everything.
7833         if (uid == 0) {
7834             return true;
7835         }
7836
7837         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7838         if (perms == null) return false;
7839
7840         // First look for exact match
7841         final UriPermission exactPerm = perms.get(grantUri);
7842         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7843             return true;
7844         }
7845
7846         // No exact match, look for prefixes
7847         final int N = perms.size();
7848         for (int i = 0; i < N; i++) {
7849             final UriPermission perm = perms.valueAt(i);
7850             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7851                     && perm.getStrength(modeFlags) >= minStrength) {
7852                 return true;
7853             }
7854         }
7855
7856         return false;
7857     }
7858
7859     /**
7860      * @param uri This uri must NOT contain an embedded userId.
7861      * @param userId The userId in which the uri is to be resolved.
7862      */
7863     @Override
7864     public int checkUriPermission(Uri uri, int pid, int uid,
7865             final int modeFlags, int userId, IBinder callerToken) {
7866         enforceNotIsolatedCaller("checkUriPermission");
7867
7868         // Another redirected-binder-call permissions check as in
7869         // {@link checkPermissionWithToken}.
7870         Identity tlsIdentity = sCallerIdentity.get();
7871         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7872             uid = tlsIdentity.uid;
7873             pid = tlsIdentity.pid;
7874         }
7875
7876         // Our own process gets to do everything.
7877         if (pid == MY_PID) {
7878             return PackageManager.PERMISSION_GRANTED;
7879         }
7880         synchronized (this) {
7881             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7882                     ? PackageManager.PERMISSION_GRANTED
7883                     : PackageManager.PERMISSION_DENIED;
7884         }
7885     }
7886
7887     /**
7888      * Check if the targetPkg can be granted permission to access uri by
7889      * the callingUid using the given modeFlags.  Throws a security exception
7890      * if callingUid is not allowed to do this.  Returns the uid of the target
7891      * if the URI permission grant should be performed; returns -1 if it is not
7892      * needed (for example targetPkg already has permission to access the URI).
7893      * If you already know the uid of the target, you can supply it in
7894      * lastTargetUid else set that to -1.
7895      */
7896     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7897             final int modeFlags, int lastTargetUid) {
7898         if (!Intent.isAccessUriMode(modeFlags)) {
7899             return -1;
7900         }
7901
7902         if (targetPkg != null) {
7903             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7904                     "Checking grant " + targetPkg + " permission to " + grantUri);
7905         }
7906
7907         final IPackageManager pm = AppGlobals.getPackageManager();
7908
7909         // If this is not a content: uri, we can't do anything with it.
7910         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7911             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7912                     "Can't grant URI permission for non-content URI: " + grantUri);
7913             return -1;
7914         }
7915
7916         final String authority = grantUri.uri.getAuthority();
7917         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7918         if (pi == null) {
7919             Slog.w(TAG, "No content provider found for permission check: " +
7920                     grantUri.uri.toSafeString());
7921             return -1;
7922         }
7923
7924         int targetUid = lastTargetUid;
7925         if (targetUid < 0 && targetPkg != null) {
7926             try {
7927                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7928                         UserHandle.getUserId(callingUid));
7929                 if (targetUid < 0) {
7930                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7931                             "Can't grant URI permission no uid for: " + targetPkg);
7932                     return -1;
7933                 }
7934             } catch (RemoteException ex) {
7935                 return -1;
7936             }
7937         }
7938
7939         if (targetUid >= 0) {
7940             // First...  does the target actually need this permission?
7941             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7942                 // No need to grant the target this permission.
7943                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7944                         "Target " + targetPkg + " already has full permission to " + grantUri);
7945                 return -1;
7946             }
7947         } else {
7948             // First...  there is no target package, so can anyone access it?
7949             boolean allowed = pi.exported;
7950             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7951                 if (pi.readPermission != null) {
7952                     allowed = false;
7953                 }
7954             }
7955             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7956                 if (pi.writePermission != null) {
7957                     allowed = false;
7958                 }
7959             }
7960             if (allowed) {
7961                 return -1;
7962             }
7963         }
7964
7965         /* There is a special cross user grant if:
7966          * - The target is on another user.
7967          * - Apps on the current user can access the uri without any uid permissions.
7968          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7969          * grant uri permissions.
7970          */
7971         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7972                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7973                 modeFlags, false /*without considering the uid permissions*/);
7974
7975         // Second...  is the provider allowing granting of URI permissions?
7976         if (!specialCrossUserGrant) {
7977             if (!pi.grantUriPermissions) {
7978                 throw new SecurityException("Provider " + pi.packageName
7979                         + "/" + pi.name
7980                         + " does not allow granting of Uri permissions (uri "
7981                         + grantUri + ")");
7982             }
7983             if (pi.uriPermissionPatterns != null) {
7984                 final int N = pi.uriPermissionPatterns.length;
7985                 boolean allowed = false;
7986                 for (int i=0; i<N; i++) {
7987                     if (pi.uriPermissionPatterns[i] != null
7988                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7989                         allowed = true;
7990                         break;
7991                     }
7992                 }
7993                 if (!allowed) {
7994                     throw new SecurityException("Provider " + pi.packageName
7995                             + "/" + pi.name
7996                             + " does not allow granting of permission to path of Uri "
7997                             + grantUri);
7998                 }
7999             }
8000         }
8001
8002         // Third...  does the caller itself have permission to access
8003         // this uri?
8004         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8005             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8006                 // Require they hold a strong enough Uri permission
8007                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8008                     throw new SecurityException("Uid " + callingUid
8009                             + " does not have permission to uri " + grantUri);
8010                 }
8011             }
8012         }
8013         return targetUid;
8014     }
8015
8016     /**
8017      * @param uri This uri must NOT contain an embedded userId.
8018      * @param userId The userId in which the uri is to be resolved.
8019      */
8020     @Override
8021     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8022             final int modeFlags, int userId) {
8023         enforceNotIsolatedCaller("checkGrantUriPermission");
8024         synchronized(this) {
8025             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8026                     new GrantUri(userId, uri, false), modeFlags, -1);
8027         }
8028     }
8029
8030     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8031             final int modeFlags, UriPermissionOwner owner) {
8032         if (!Intent.isAccessUriMode(modeFlags)) {
8033             return;
8034         }
8035
8036         // So here we are: the caller has the assumed permission
8037         // to the uri, and the target doesn't.  Let's now give this to
8038         // the target.
8039
8040         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8041                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8042
8043         final String authority = grantUri.uri.getAuthority();
8044         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8045         if (pi == null) {
8046             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8047             return;
8048         }
8049
8050         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8051             grantUri.prefix = true;
8052         }
8053         final UriPermission perm = findOrCreateUriPermissionLocked(
8054                 pi.packageName, targetPkg, targetUid, grantUri);
8055         perm.grantModes(modeFlags, owner);
8056     }
8057
8058     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8059             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8060         if (targetPkg == null) {
8061             throw new NullPointerException("targetPkg");
8062         }
8063         int targetUid;
8064         final IPackageManager pm = AppGlobals.getPackageManager();
8065         try {
8066             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8067         } catch (RemoteException ex) {
8068             return;
8069         }
8070
8071         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8072                 targetUid);
8073         if (targetUid < 0) {
8074             return;
8075         }
8076
8077         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8078                 owner);
8079     }
8080
8081     static class NeededUriGrants extends ArrayList<GrantUri> {
8082         final String targetPkg;
8083         final int targetUid;
8084         final int flags;
8085
8086         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8087             this.targetPkg = targetPkg;
8088             this.targetUid = targetUid;
8089             this.flags = flags;
8090         }
8091     }
8092
8093     /**
8094      * Like checkGrantUriPermissionLocked, but takes an Intent.
8095      */
8096     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8097             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8098         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8100                 + " clip=" + (intent != null ? intent.getClipData() : null)
8101                 + " from " + intent + "; flags=0x"
8102                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8103
8104         if (targetPkg == null) {
8105             throw new NullPointerException("targetPkg");
8106         }
8107
8108         if (intent == null) {
8109             return null;
8110         }
8111         Uri data = intent.getData();
8112         ClipData clip = intent.getClipData();
8113         if (data == null && clip == null) {
8114             return null;
8115         }
8116         // Default userId for uris in the intent (if they don't specify it themselves)
8117         int contentUserHint = intent.getContentUserHint();
8118         if (contentUserHint == UserHandle.USER_CURRENT) {
8119             contentUserHint = UserHandle.getUserId(callingUid);
8120         }
8121         final IPackageManager pm = AppGlobals.getPackageManager();
8122         int targetUid;
8123         if (needed != null) {
8124             targetUid = needed.targetUid;
8125         } else {
8126             try {
8127                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8128                         targetUserId);
8129             } catch (RemoteException ex) {
8130                 return null;
8131             }
8132             if (targetUid < 0) {
8133                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                         "Can't grant URI permission no uid for: " + targetPkg
8135                         + " on user " + targetUserId);
8136                 return null;
8137             }
8138         }
8139         if (data != null) {
8140             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8141             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8142                     targetUid);
8143             if (targetUid > 0) {
8144                 if (needed == null) {
8145                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8146                 }
8147                 needed.add(grantUri);
8148             }
8149         }
8150         if (clip != null) {
8151             for (int i=0; i<clip.getItemCount(); i++) {
8152                 Uri uri = clip.getItemAt(i).getUri();
8153                 if (uri != null) {
8154                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8155                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8156                             targetUid);
8157                     if (targetUid > 0) {
8158                         if (needed == null) {
8159                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8160                         }
8161                         needed.add(grantUri);
8162                     }
8163                 } else {
8164                     Intent clipIntent = clip.getItemAt(i).getIntent();
8165                     if (clipIntent != null) {
8166                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8167                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8168                         if (newNeeded != null) {
8169                             needed = newNeeded;
8170                         }
8171                     }
8172                 }
8173             }
8174         }
8175
8176         return needed;
8177     }
8178
8179     /**
8180      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8181      */
8182     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8183             UriPermissionOwner owner) {
8184         if (needed != null) {
8185             for (int i=0; i<needed.size(); i++) {
8186                 GrantUri grantUri = needed.get(i);
8187                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8188                         grantUri, needed.flags, owner);
8189             }
8190         }
8191     }
8192
8193     void grantUriPermissionFromIntentLocked(int callingUid,
8194             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8195         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8196                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8197         if (needed == null) {
8198             return;
8199         }
8200
8201         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8202     }
8203
8204     /**
8205      * @param uri This uri must NOT contain an embedded userId.
8206      * @param userId The userId in which the uri is to be resolved.
8207      */
8208     @Override
8209     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8210             final int modeFlags, int userId) {
8211         enforceNotIsolatedCaller("grantUriPermission");
8212         GrantUri grantUri = new GrantUri(userId, uri, false);
8213         synchronized(this) {
8214             final ProcessRecord r = getRecordForAppLocked(caller);
8215             if (r == null) {
8216                 throw new SecurityException("Unable to find app for caller "
8217                         + caller
8218                         + " when granting permission to uri " + grantUri);
8219             }
8220             if (targetPkg == null) {
8221                 throw new IllegalArgumentException("null target");
8222             }
8223             if (grantUri == null) {
8224                 throw new IllegalArgumentException("null uri");
8225             }
8226
8227             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8228                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8229                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8230                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8231
8232             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8233                     UserHandle.getUserId(r.uid));
8234         }
8235     }
8236
8237     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8238         if (perm.modeFlags == 0) {
8239             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8240                     perm.targetUid);
8241             if (perms != null) {
8242                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8243                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8244
8245                 perms.remove(perm.uri);
8246                 if (perms.isEmpty()) {
8247                     mGrantedUriPermissions.remove(perm.targetUid);
8248                 }
8249             }
8250         }
8251     }
8252
8253     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8254         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8255                 "Revoking all granted permissions to " + grantUri);
8256
8257         final IPackageManager pm = AppGlobals.getPackageManager();
8258         final String authority = grantUri.uri.getAuthority();
8259         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8260         if (pi == null) {
8261             Slog.w(TAG, "No content provider found for permission revoke: "
8262                     + grantUri.toSafeString());
8263             return;
8264         }
8265
8266         // Does the caller have this permission on the URI?
8267         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8268             // If they don't have direct access to the URI, then revoke any
8269             // ownerless URI permissions that have been granted to them.
8270             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8271             if (perms != null) {
8272                 boolean persistChanged = false;
8273                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8274                     final UriPermission perm = it.next();
8275                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8276                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8277                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8278                                 "Revoking non-owned " + perm.targetUid
8279                                 + " permission to " + perm.uri);
8280                         persistChanged |= perm.revokeModes(
8281                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8282                         if (perm.modeFlags == 0) {
8283                             it.remove();
8284                         }
8285                     }
8286                 }
8287                 if (perms.isEmpty()) {
8288                     mGrantedUriPermissions.remove(callingUid);
8289                 }
8290                 if (persistChanged) {
8291                     schedulePersistUriGrants();
8292                 }
8293             }
8294             return;
8295         }
8296
8297         boolean persistChanged = false;
8298
8299         // Go through all of the permissions and remove any that match.
8300         int N = mGrantedUriPermissions.size();
8301         for (int i = 0; i < N; i++) {
8302             final int targetUid = mGrantedUriPermissions.keyAt(i);
8303             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8304
8305             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8306                 final UriPermission perm = it.next();
8307                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8308                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8309                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8310                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8311                     persistChanged |= perm.revokeModes(
8312                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8313                     if (perm.modeFlags == 0) {
8314                         it.remove();
8315                     }
8316                 }
8317             }
8318
8319             if (perms.isEmpty()) {
8320                 mGrantedUriPermissions.remove(targetUid);
8321                 N--;
8322                 i--;
8323             }
8324         }
8325
8326         if (persistChanged) {
8327             schedulePersistUriGrants();
8328         }
8329     }
8330
8331     /**
8332      * @param uri This uri must NOT contain an embedded userId.
8333      * @param userId The userId in which the uri is to be resolved.
8334      */
8335     @Override
8336     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8337             int userId) {
8338         enforceNotIsolatedCaller("revokeUriPermission");
8339         synchronized(this) {
8340             final ProcessRecord r = getRecordForAppLocked(caller);
8341             if (r == null) {
8342                 throw new SecurityException("Unable to find app for caller "
8343                         + caller
8344                         + " when revoking permission to uri " + uri);
8345             }
8346             if (uri == null) {
8347                 Slog.w(TAG, "revokeUriPermission: null uri");
8348                 return;
8349             }
8350
8351             if (!Intent.isAccessUriMode(modeFlags)) {
8352                 return;
8353             }
8354
8355             final String authority = uri.getAuthority();
8356             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8357             if (pi == null) {
8358                 Slog.w(TAG, "No content provider found for permission revoke: "
8359                         + uri.toSafeString());
8360                 return;
8361             }
8362
8363             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8364         }
8365     }
8366
8367     /**
8368      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8369      * given package.
8370      *
8371      * @param packageName Package name to match, or {@code null} to apply to all
8372      *            packages.
8373      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8374      *            to all users.
8375      * @param persistable If persistable grants should be removed.
8376      */
8377     private void removeUriPermissionsForPackageLocked(
8378             String packageName, int userHandle, boolean persistable) {
8379         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8380             throw new IllegalArgumentException("Must narrow by either package or user");
8381         }
8382
8383         boolean persistChanged = false;
8384
8385         int N = mGrantedUriPermissions.size();
8386         for (int i = 0; i < N; i++) {
8387             final int targetUid = mGrantedUriPermissions.keyAt(i);
8388             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8389
8390             // Only inspect grants matching user
8391             if (userHandle == UserHandle.USER_ALL
8392                     || userHandle == UserHandle.getUserId(targetUid)) {
8393                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8394                     final UriPermission perm = it.next();
8395
8396                     // Only inspect grants matching package
8397                     if (packageName == null || perm.sourcePkg.equals(packageName)
8398                             || perm.targetPkg.equals(packageName)) {
8399                         persistChanged |= perm.revokeModes(persistable
8400                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8401
8402                         // Only remove when no modes remain; any persisted grants
8403                         // will keep this alive.
8404                         if (perm.modeFlags == 0) {
8405                             it.remove();
8406                         }
8407                     }
8408                 }
8409
8410                 if (perms.isEmpty()) {
8411                     mGrantedUriPermissions.remove(targetUid);
8412                     N--;
8413                     i--;
8414                 }
8415             }
8416         }
8417
8418         if (persistChanged) {
8419             schedulePersistUriGrants();
8420         }
8421     }
8422
8423     @Override
8424     public IBinder newUriPermissionOwner(String name) {
8425         enforceNotIsolatedCaller("newUriPermissionOwner");
8426         synchronized(this) {
8427             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8428             return owner.getExternalTokenLocked();
8429         }
8430     }
8431
8432     @Override
8433     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8434         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8435         synchronized(this) {
8436             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8437             if (r == null) {
8438                 throw new IllegalArgumentException("Activity does not exist; token="
8439                         + activityToken);
8440             }
8441             return r.getUriPermissionsLocked().getExternalTokenLocked();
8442         }
8443     }
8444     /**
8445      * @param uri This uri must NOT contain an embedded userId.
8446      * @param sourceUserId The userId in which the uri is to be resolved.
8447      * @param targetUserId The userId of the app that receives the grant.
8448      */
8449     @Override
8450     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8451             final int modeFlags, int sourceUserId, int targetUserId) {
8452         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8453                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8454                 "grantUriPermissionFromOwner", null);
8455         synchronized(this) {
8456             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8457             if (owner == null) {
8458                 throw new IllegalArgumentException("Unknown owner: " + token);
8459             }
8460             if (fromUid != Binder.getCallingUid()) {
8461                 if (Binder.getCallingUid() != Process.myUid()) {
8462                     // Only system code can grant URI permissions on behalf
8463                     // of other users.
8464                     throw new SecurityException("nice try");
8465                 }
8466             }
8467             if (targetPkg == null) {
8468                 throw new IllegalArgumentException("null target");
8469             }
8470             if (uri == null) {
8471                 throw new IllegalArgumentException("null uri");
8472             }
8473
8474             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8475                     modeFlags, owner, targetUserId);
8476         }
8477     }
8478
8479     /**
8480      * @param uri This uri must NOT contain an embedded userId.
8481      * @param userId The userId in which the uri is to be resolved.
8482      */
8483     @Override
8484     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8485         synchronized(this) {
8486             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8487             if (owner == null) {
8488                 throw new IllegalArgumentException("Unknown owner: " + token);
8489             }
8490
8491             if (uri == null) {
8492                 owner.removeUriPermissionsLocked(mode);
8493             } else {
8494                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8495             }
8496         }
8497     }
8498
8499     private void schedulePersistUriGrants() {
8500         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8501             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8502                     10 * DateUtils.SECOND_IN_MILLIS);
8503         }
8504     }
8505
8506     private void writeGrantedUriPermissions() {
8507         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8508
8509         // Snapshot permissions so we can persist without lock
8510         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8511         synchronized (this) {
8512             final int size = mGrantedUriPermissions.size();
8513             for (int i = 0; i < size; i++) {
8514                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8515                 for (UriPermission perm : perms.values()) {
8516                     if (perm.persistedModeFlags != 0) {
8517                         persist.add(perm.snapshot());
8518                     }
8519                 }
8520             }
8521         }
8522
8523         FileOutputStream fos = null;
8524         try {
8525             fos = mGrantFile.startWrite();
8526
8527             XmlSerializer out = new FastXmlSerializer();
8528             out.setOutput(fos, StandardCharsets.UTF_8.name());
8529             out.startDocument(null, true);
8530             out.startTag(null, TAG_URI_GRANTS);
8531             for (UriPermission.Snapshot perm : persist) {
8532                 out.startTag(null, TAG_URI_GRANT);
8533                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8534                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8535                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8536                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8537                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8538                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8539                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8540                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8541                 out.endTag(null, TAG_URI_GRANT);
8542             }
8543             out.endTag(null, TAG_URI_GRANTS);
8544             out.endDocument();
8545
8546             mGrantFile.finishWrite(fos);
8547         } catch (IOException e) {
8548             if (fos != null) {
8549                 mGrantFile.failWrite(fos);
8550             }
8551         }
8552     }
8553
8554     private void readGrantedUriPermissionsLocked() {
8555         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8556
8557         final long now = System.currentTimeMillis();
8558
8559         FileInputStream fis = null;
8560         try {
8561             fis = mGrantFile.openRead();
8562             final XmlPullParser in = Xml.newPullParser();
8563             in.setInput(fis, StandardCharsets.UTF_8.name());
8564
8565             int type;
8566             while ((type = in.next()) != END_DOCUMENT) {
8567                 final String tag = in.getName();
8568                 if (type == START_TAG) {
8569                     if (TAG_URI_GRANT.equals(tag)) {
8570                         final int sourceUserId;
8571                         final int targetUserId;
8572                         final int userHandle = readIntAttribute(in,
8573                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8574                         if (userHandle != UserHandle.USER_NULL) {
8575                             // For backwards compatibility.
8576                             sourceUserId = userHandle;
8577                             targetUserId = userHandle;
8578                         } else {
8579                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8580                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8581                         }
8582                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8583                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8584                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8585                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8586                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8587                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8588
8589                         // Sanity check that provider still belongs to source package
8590                         final ProviderInfo pi = getProviderInfoLocked(
8591                                 uri.getAuthority(), sourceUserId);
8592                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8593                             int targetUid = -1;
8594                             try {
8595                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8596                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8597                             } catch (RemoteException e) {
8598                             }
8599                             if (targetUid != -1) {
8600                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8601                                         sourcePkg, targetPkg, targetUid,
8602                                         new GrantUri(sourceUserId, uri, prefix));
8603                                 perm.initPersistedModes(modeFlags, createdTime);
8604                             }
8605                         } else {
8606                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8607                                     + " but instead found " + pi);
8608                         }
8609                     }
8610                 }
8611             }
8612         } catch (FileNotFoundException e) {
8613             // Missing grants is okay
8614         } catch (IOException e) {
8615             Slog.wtf(TAG, "Failed reading Uri grants", e);
8616         } catch (XmlPullParserException e) {
8617             Slog.wtf(TAG, "Failed reading Uri grants", e);
8618         } finally {
8619             IoUtils.closeQuietly(fis);
8620         }
8621     }
8622
8623     /**
8624      * @param uri This uri must NOT contain an embedded userId.
8625      * @param userId The userId in which the uri is to be resolved.
8626      */
8627     @Override
8628     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8629         enforceNotIsolatedCaller("takePersistableUriPermission");
8630
8631         Preconditions.checkFlagsArgument(modeFlags,
8632                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8633
8634         synchronized (this) {
8635             final int callingUid = Binder.getCallingUid();
8636             boolean persistChanged = false;
8637             GrantUri grantUri = new GrantUri(userId, uri, false);
8638
8639             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8640                     new GrantUri(userId, uri, false));
8641             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8642                     new GrantUri(userId, uri, true));
8643
8644             final boolean exactValid = (exactPerm != null)
8645                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8646             final boolean prefixValid = (prefixPerm != null)
8647                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8648
8649             if (!(exactValid || prefixValid)) {
8650                 throw new SecurityException("No persistable permission grants found for UID "
8651                         + callingUid + " and Uri " + grantUri.toSafeString());
8652             }
8653
8654             if (exactValid) {
8655                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8656             }
8657             if (prefixValid) {
8658                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8659             }
8660
8661             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8662
8663             if (persistChanged) {
8664                 schedulePersistUriGrants();
8665             }
8666         }
8667     }
8668
8669     /**
8670      * @param uri This uri must NOT contain an embedded userId.
8671      * @param userId The userId in which the uri is to be resolved.
8672      */
8673     @Override
8674     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8675         enforceNotIsolatedCaller("releasePersistableUriPermission");
8676
8677         Preconditions.checkFlagsArgument(modeFlags,
8678                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8679
8680         synchronized (this) {
8681             final int callingUid = Binder.getCallingUid();
8682             boolean persistChanged = false;
8683
8684             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8685                     new GrantUri(userId, uri, false));
8686             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8687                     new GrantUri(userId, uri, true));
8688             if (exactPerm == null && prefixPerm == null) {
8689                 throw new SecurityException("No permission grants found for UID " + callingUid
8690                         + " and Uri " + uri.toSafeString());
8691             }
8692
8693             if (exactPerm != null) {
8694                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8695                 removeUriPermissionIfNeededLocked(exactPerm);
8696             }
8697             if (prefixPerm != null) {
8698                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8699                 removeUriPermissionIfNeededLocked(prefixPerm);
8700             }
8701
8702             if (persistChanged) {
8703                 schedulePersistUriGrants();
8704             }
8705         }
8706     }
8707
8708     /**
8709      * Prune any older {@link UriPermission} for the given UID until outstanding
8710      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8711      *
8712      * @return if any mutations occured that require persisting.
8713      */
8714     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8715         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8716         if (perms == null) return false;
8717         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8718
8719         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8720         for (UriPermission perm : perms.values()) {
8721             if (perm.persistedModeFlags != 0) {
8722                 persisted.add(perm);
8723             }
8724         }
8725
8726         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8727         if (trimCount <= 0) return false;
8728
8729         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8730         for (int i = 0; i < trimCount; i++) {
8731             final UriPermission perm = persisted.get(i);
8732
8733             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8734                     "Trimming grant created at " + perm.persistedCreateTime);
8735
8736             perm.releasePersistableModes(~0);
8737             removeUriPermissionIfNeededLocked(perm);
8738         }
8739
8740         return true;
8741     }
8742
8743     @Override
8744     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8745             String packageName, boolean incoming) {
8746         enforceNotIsolatedCaller("getPersistedUriPermissions");
8747         Preconditions.checkNotNull(packageName, "packageName");
8748
8749         final int callingUid = Binder.getCallingUid();
8750         final IPackageManager pm = AppGlobals.getPackageManager();
8751         try {
8752             final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8753                     UserHandle.getUserId(callingUid));
8754             if (packageUid != callingUid) {
8755                 throw new SecurityException(
8756                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8757             }
8758         } catch (RemoteException e) {
8759             throw new SecurityException("Failed to verify package name ownership");
8760         }
8761
8762         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8763         synchronized (this) {
8764             if (incoming) {
8765                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8766                         callingUid);
8767                 if (perms == null) {
8768                     Slog.w(TAG, "No permission grants found for " + packageName);
8769                 } else {
8770                     for (UriPermission perm : perms.values()) {
8771                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8772                             result.add(perm.buildPersistedPublicApiObject());
8773                         }
8774                     }
8775                 }
8776             } else {
8777                 final int size = mGrantedUriPermissions.size();
8778                 for (int i = 0; i < size; i++) {
8779                     final ArrayMap<GrantUri, UriPermission> perms =
8780                             mGrantedUriPermissions.valueAt(i);
8781                     for (UriPermission perm : perms.values()) {
8782                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8783                             result.add(perm.buildPersistedPublicApiObject());
8784                         }
8785                     }
8786                 }
8787             }
8788         }
8789         return new ParceledListSlice<android.content.UriPermission>(result);
8790     }
8791
8792     @Override
8793     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8794             String packageName, int userId) {
8795         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8796                 "getGrantedUriPermissions");
8797
8798         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8799         synchronized (this) {
8800             final int size = mGrantedUriPermissions.size();
8801             for (int i = 0; i < size; i++) {
8802                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8803                 for (UriPermission perm : perms.values()) {
8804                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8805                             && perm.persistedModeFlags != 0) {
8806                         result.add(perm.buildPersistedPublicApiObject());
8807                     }
8808                 }
8809             }
8810         }
8811         return new ParceledListSlice<android.content.UriPermission>(result);
8812     }
8813
8814     @Override
8815     public void clearGrantedUriPermissions(String packageName, int userId) {
8816         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8817                 "clearGrantedUriPermissions");
8818         removeUriPermissionsForPackageLocked(packageName, userId, true);
8819     }
8820
8821     @Override
8822     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8823         synchronized (this) {
8824             ProcessRecord app =
8825                 who != null ? getRecordForAppLocked(who) : null;
8826             if (app == null) return;
8827
8828             Message msg = Message.obtain();
8829             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8830             msg.obj = app;
8831             msg.arg1 = waiting ? 1 : 0;
8832             mUiHandler.sendMessage(msg);
8833         }
8834     }
8835
8836     @Override
8837     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8838         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8839         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8840         outInfo.availMem = Process.getFreeMemory();
8841         outInfo.totalMem = Process.getTotalMemory();
8842         outInfo.threshold = homeAppMem;
8843         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8844         outInfo.hiddenAppThreshold = cachedAppMem;
8845         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8846                 ProcessList.SERVICE_ADJ);
8847         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8848                 ProcessList.VISIBLE_APP_ADJ);
8849         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8850                 ProcessList.FOREGROUND_APP_ADJ);
8851     }
8852
8853     // =========================================================
8854     // TASK MANAGEMENT
8855     // =========================================================
8856
8857     @Override
8858     public List<IAppTask> getAppTasks(String callingPackage) {
8859         int callingUid = Binder.getCallingUid();
8860         long ident = Binder.clearCallingIdentity();
8861
8862         synchronized(this) {
8863             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8864             try {
8865                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8866
8867                 final int N = mRecentTasks.size();
8868                 for (int i = 0; i < N; i++) {
8869                     TaskRecord tr = mRecentTasks.get(i);
8870                     // Skip tasks that do not match the caller.  We don't need to verify
8871                     // callingPackage, because we are also limiting to callingUid and know
8872                     // that will limit to the correct security sandbox.
8873                     if (tr.effectiveUid != callingUid) {
8874                         continue;
8875                     }
8876                     Intent intent = tr.getBaseIntent();
8877                     if (intent == null ||
8878                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8879                         continue;
8880                     }
8881                     ActivityManager.RecentTaskInfo taskInfo =
8882                             createRecentTaskInfoFromTaskRecord(tr);
8883                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8884                     list.add(taskImpl);
8885                 }
8886             } finally {
8887                 Binder.restoreCallingIdentity(ident);
8888             }
8889             return list;
8890         }
8891     }
8892
8893     @Override
8894     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8895         final int callingUid = Binder.getCallingUid();
8896         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8897
8898         synchronized(this) {
8899             if (DEBUG_ALL) Slog.v(
8900                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8901
8902             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8903                     callingUid);
8904
8905             // TODO: Improve with MRU list from all ActivityStacks.
8906             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8907         }
8908
8909         return list;
8910     }
8911
8912     /**
8913      * Creates a new RecentTaskInfo from a TaskRecord.
8914      */
8915     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8916         // Update the task description to reflect any changes in the task stack
8917         tr.updateTaskDescription();
8918
8919         // Compose the recent task info
8920         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8921         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8922         rti.persistentId = tr.taskId;
8923         rti.baseIntent = new Intent(tr.getBaseIntent());
8924         rti.origActivity = tr.origActivity;
8925         rti.realActivity = tr.realActivity;
8926         rti.description = tr.lastDescription;
8927         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8928         rti.userId = tr.userId;
8929         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8930         rti.firstActiveTime = tr.firstActiveTime;
8931         rti.lastActiveTime = tr.lastActiveTime;
8932         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8933         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8934         rti.numActivities = 0;
8935         if (tr.mBounds != null) {
8936             rti.bounds = new Rect(tr.mBounds);
8937         }
8938         rti.isDockable = tr.canGoInDockedStack();
8939         rti.resizeMode = tr.mResizeMode;
8940
8941         ActivityRecord base = null;
8942         ActivityRecord top = null;
8943         ActivityRecord tmp;
8944
8945         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8946             tmp = tr.mActivities.get(i);
8947             if (tmp.finishing) {
8948                 continue;
8949             }
8950             base = tmp;
8951             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8952                 top = base;
8953             }
8954             rti.numActivities++;
8955         }
8956
8957         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8958         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8959
8960         return rti;
8961     }
8962
8963     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8964         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8965                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8966         if (!allowed) {
8967             if (checkPermission(android.Manifest.permission.GET_TASKS,
8968                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8969                 // Temporary compatibility: some existing apps on the system image may
8970                 // still be requesting the old permission and not switched to the new
8971                 // one; if so, we'll still allow them full access.  This means we need
8972                 // to see if they are holding the old permission and are a system app.
8973                 try {
8974                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8975                         allowed = true;
8976                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8977                                 + " is using old GET_TASKS but privileged; allowing");
8978                     }
8979                 } catch (RemoteException e) {
8980                 }
8981             }
8982         }
8983         if (!allowed) {
8984             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8985                     + " does not hold REAL_GET_TASKS; limiting output");
8986         }
8987         return allowed;
8988     }
8989
8990     @Override
8991     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8992         final int callingUid = Binder.getCallingUid();
8993         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8994                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8995
8996         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8997         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8998         synchronized (this) {
8999             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9000                     callingUid);
9001             final boolean detailed = checkCallingPermission(
9002                     android.Manifest.permission.GET_DETAILED_TASKS)
9003                     == PackageManager.PERMISSION_GRANTED;
9004
9005             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9006                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9007                 return Collections.emptyList();
9008             }
9009             mRecentTasks.loadUserRecentsLocked(userId);
9010
9011             final int recentsCount = mRecentTasks.size();
9012             ArrayList<ActivityManager.RecentTaskInfo> res =
9013                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9014
9015             final Set<Integer> includedUsers;
9016             if (includeProfiles) {
9017                 includedUsers = mUserController.getProfileIds(userId);
9018             } else {
9019                 includedUsers = new HashSet<>();
9020             }
9021             includedUsers.add(Integer.valueOf(userId));
9022
9023             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9024                 TaskRecord tr = mRecentTasks.get(i);
9025                 // Only add calling user or related users recent tasks
9026                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9027                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9028                     continue;
9029                 }
9030
9031                 if (tr.realActivitySuspended) {
9032                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9033                     continue;
9034                 }
9035
9036                 // Return the entry if desired by the caller.  We always return
9037                 // the first entry, because callers always expect this to be the
9038                 // foreground app.  We may filter others if the caller has
9039                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9040                 // we should exclude the entry.
9041
9042                 if (i == 0
9043                         || withExcluded
9044                         || (tr.intent == null)
9045                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9046                                 == 0)) {
9047                     if (!allowed) {
9048                         // If the caller doesn't have the GET_TASKS permission, then only
9049                         // allow them to see a small subset of tasks -- their own and home.
9050                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9051                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9052                             continue;
9053                         }
9054                     }
9055                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9056                         if (tr.stack != null && tr.stack.isHomeStack()) {
9057                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9058                                     "Skipping, home stack task: " + tr);
9059                             continue;
9060                         }
9061                     }
9062                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9063                         final ActivityStack stack = tr.stack;
9064                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9065                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9066                                     "Skipping, top task in docked stack: " + tr);
9067                             continue;
9068                         }
9069                     }
9070                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9071                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9072                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9073                                     "Skipping, pinned stack task: " + tr);
9074                             continue;
9075                         }
9076                     }
9077                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9078                         // Don't include auto remove tasks that are finished or finishing.
9079                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9080                                 "Skipping, auto-remove without activity: " + tr);
9081                         continue;
9082                     }
9083                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9084                             && !tr.isAvailable) {
9085                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9086                                 "Skipping, unavail real act: " + tr);
9087                         continue;
9088                     }
9089
9090                     if (!tr.mUserSetupComplete) {
9091                         // Don't include task launched while user is not done setting-up.
9092                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9093                                 "Skipping, user setup not complete: " + tr);
9094                         continue;
9095                     }
9096
9097                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9098                     if (!detailed) {
9099                         rti.baseIntent.replaceExtras((Bundle)null);
9100                     }
9101
9102                     res.add(rti);
9103                     maxNum--;
9104                 }
9105             }
9106             return res;
9107         }
9108     }
9109
9110     @Override
9111     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9112         synchronized (this) {
9113             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9114                     "getTaskThumbnail()");
9115             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9116                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9117             if (tr != null) {
9118                 return tr.getTaskThumbnailLocked();
9119             }
9120         }
9121         return null;
9122     }
9123
9124     @Override
9125     public int addAppTask(IBinder activityToken, Intent intent,
9126             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9127         final int callingUid = Binder.getCallingUid();
9128         final long callingIdent = Binder.clearCallingIdentity();
9129
9130         try {
9131             synchronized (this) {
9132                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9133                 if (r == null) {
9134                     throw new IllegalArgumentException("Activity does not exist; token="
9135                             + activityToken);
9136                 }
9137                 ComponentName comp = intent.getComponent();
9138                 if (comp == null) {
9139                     throw new IllegalArgumentException("Intent " + intent
9140                             + " must specify explicit component");
9141                 }
9142                 if (thumbnail.getWidth() != mThumbnailWidth
9143                         || thumbnail.getHeight() != mThumbnailHeight) {
9144                     throw new IllegalArgumentException("Bad thumbnail size: got "
9145                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9146                             + mThumbnailWidth + "x" + mThumbnailHeight);
9147                 }
9148                 if (intent.getSelector() != null) {
9149                     intent.setSelector(null);
9150                 }
9151                 if (intent.getSourceBounds() != null) {
9152                     intent.setSourceBounds(null);
9153                 }
9154                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9155                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9156                         // The caller has added this as an auto-remove task...  that makes no
9157                         // sense, so turn off auto-remove.
9158                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9159                     }
9160                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9161                     // Must be a new task.
9162                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9163                 }
9164                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9165                     mLastAddedTaskActivity = null;
9166                 }
9167                 ActivityInfo ainfo = mLastAddedTaskActivity;
9168                 if (ainfo == null) {
9169                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9170                             comp, 0, UserHandle.getUserId(callingUid));
9171                     if (ainfo.applicationInfo.uid != callingUid) {
9172                         throw new SecurityException(
9173                                 "Can't add task for another application: target uid="
9174                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9175                     }
9176                 }
9177
9178                 // Use the full screen as the context for the task thumbnail
9179                 final Point displaySize = new Point();
9180                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9181                 r.task.stack.getDisplaySize(displaySize);
9182                 thumbnailInfo.taskWidth = displaySize.x;
9183                 thumbnailInfo.taskHeight = displaySize.y;
9184                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9185
9186                 TaskRecord task = new TaskRecord(this,
9187                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9188                         ainfo, intent, description, thumbnailInfo);
9189
9190                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9191                 if (trimIdx >= 0) {
9192                     // If this would have caused a trim, then we'll abort because that
9193                     // means it would be added at the end of the list but then just removed.
9194                     return INVALID_TASK_ID;
9195                 }
9196
9197                 final int N = mRecentTasks.size();
9198                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9199                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9200                     tr.removedFromRecents();
9201                 }
9202
9203                 task.inRecents = true;
9204                 mRecentTasks.add(task);
9205                 r.task.stack.addTask(task, false, "addAppTask");
9206
9207                 task.setLastThumbnailLocked(thumbnail);
9208                 task.freeLastThumbnail();
9209
9210                 return task.taskId;
9211             }
9212         } finally {
9213             Binder.restoreCallingIdentity(callingIdent);
9214         }
9215     }
9216
9217     @Override
9218     public Point getAppTaskThumbnailSize() {
9219         synchronized (this) {
9220             return new Point(mThumbnailWidth,  mThumbnailHeight);
9221         }
9222     }
9223
9224     @Override
9225     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9226         synchronized (this) {
9227             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9228             if (r != null) {
9229                 r.setTaskDescription(td);
9230                 r.task.updateTaskDescription();
9231             }
9232         }
9233     }
9234
9235     @Override
9236     public void setTaskResizeable(int taskId, int resizeableMode) {
9237         synchronized (this) {
9238             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9239                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9240             if (task == null) {
9241                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9242                 return;
9243             }
9244             if (task.mResizeMode != resizeableMode) {
9245                 task.mResizeMode = resizeableMode;
9246                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9247                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9248                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9249             }
9250         }
9251     }
9252
9253     @Override
9254     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9255         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9256         long ident = Binder.clearCallingIdentity();
9257         try {
9258             synchronized (this) {
9259                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9260                 if (task == null) {
9261                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9262                     return;
9263                 }
9264                 int stackId = task.stack.mStackId;
9265                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9266                 // in crop windows resize mode or if the task size is affected by the docked stack
9267                 // changing size. No need to update configuration.
9268                 if (bounds != null && task.inCropWindowsResizeMode()
9269                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9270                     mWindowManager.scrollTask(task.taskId, bounds);
9271                     return;
9272                 }
9273
9274                 // Place the task in the right stack if it isn't there already based on
9275                 // the requested bounds.
9276                 // The stack transition logic is:
9277                 // - a null bounds on a freeform task moves that task to fullscreen
9278                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9279                 //   that task to freeform
9280                 // - otherwise the task is not moved
9281                 if (!StackId.isTaskResizeAllowed(stackId)) {
9282                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9283                 }
9284                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9285                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9286                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9287                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9288                 }
9289                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9290                 if (stackId != task.stack.mStackId) {
9291                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9292                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9293                     preserveWindow = false;
9294                 }
9295
9296                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9297                         false /* deferResume */);
9298             }
9299         } finally {
9300             Binder.restoreCallingIdentity(ident);
9301         }
9302     }
9303
9304     @Override
9305     public Rect getTaskBounds(int taskId) {
9306         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9307         long ident = Binder.clearCallingIdentity();
9308         Rect rect = new Rect();
9309         try {
9310             synchronized (this) {
9311                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9312                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9313                 if (task == null) {
9314                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9315                     return rect;
9316                 }
9317                 if (task.stack != null) {
9318                     // Return the bounds from window manager since it will be adjusted for various
9319                     // things like the presense of a docked stack for tasks that aren't resizeable.
9320                     mWindowManager.getTaskBounds(task.taskId, rect);
9321                 } else {
9322                     // Task isn't in window manager yet since it isn't associated with a stack.
9323                     // Return the persist value from activity manager
9324                     if (task.mBounds != null) {
9325                         rect.set(task.mBounds);
9326                     } else if (task.mLastNonFullscreenBounds != null) {
9327                         rect.set(task.mLastNonFullscreenBounds);
9328                     }
9329                 }
9330             }
9331         } finally {
9332             Binder.restoreCallingIdentity(ident);
9333         }
9334         return rect;
9335     }
9336
9337     @Override
9338     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9339         if (userId != UserHandle.getCallingUserId()) {
9340             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9341                     "getTaskDescriptionIcon");
9342         }
9343         final File passedIconFile = new File(filePath);
9344         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9345                 passedIconFile.getName());
9346         if (!legitIconFile.getPath().equals(filePath)
9347                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9348             throw new IllegalArgumentException("Bad file path: " + filePath
9349                     + " passed for userId " + userId);
9350         }
9351         return mRecentTasks.getTaskDescriptionIcon(filePath);
9352     }
9353
9354     @Override
9355     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9356             throws RemoteException {
9357         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9358                 opts.getCustomInPlaceResId() == 0) {
9359             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9360                     "with valid animation");
9361         }
9362         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9363         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9364                 opts.getCustomInPlaceResId());
9365         mWindowManager.executeAppTransition();
9366     }
9367
9368     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9369             boolean removeFromRecents) {
9370         if (removeFromRecents) {
9371             mRecentTasks.remove(tr);
9372             tr.removedFromRecents();
9373         }
9374         ComponentName component = tr.getBaseIntent().getComponent();
9375         if (component == null) {
9376             Slog.w(TAG, "No component for base intent of task: " + tr);
9377             return;
9378         }
9379
9380         // Find any running services associated with this app and stop if needed.
9381         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9382
9383         if (!killProcess) {
9384             return;
9385         }
9386
9387         // Determine if the process(es) for this task should be killed.
9388         final String pkg = component.getPackageName();
9389         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9390         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9391         for (int i = 0; i < pmap.size(); i++) {
9392
9393             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9394             for (int j = 0; j < uids.size(); j++) {
9395                 ProcessRecord proc = uids.valueAt(j);
9396                 if (proc.userId != tr.userId) {
9397                     // Don't kill process for a different user.
9398                     continue;
9399                 }
9400                 if (proc == mHomeProcess) {
9401                     // Don't kill the home process along with tasks from the same package.
9402                     continue;
9403                 }
9404                 if (!proc.pkgList.containsKey(pkg)) {
9405                     // Don't kill process that is not associated with this task.
9406                     continue;
9407                 }
9408
9409                 for (int k = 0; k < proc.activities.size(); k++) {
9410                     TaskRecord otherTask = proc.activities.get(k).task;
9411                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9412                         // Don't kill process(es) that has an activity in a different task that is
9413                         // also in recents.
9414                         return;
9415                     }
9416                 }
9417
9418                 if (proc.foregroundServices) {
9419                     // Don't kill process(es) with foreground service.
9420                     return;
9421                 }
9422
9423                 // Add process to kill list.
9424                 procsToKill.add(proc);
9425             }
9426         }
9427
9428         // Kill the running processes.
9429         for (int i = 0; i < procsToKill.size(); i++) {
9430             ProcessRecord pr = procsToKill.get(i);
9431             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9432                     && pr.curReceiver == null) {
9433                 pr.kill("remove task", true);
9434             } else {
9435                 // We delay killing processes that are not in the background or running a receiver.
9436                 pr.waitingToKill = "remove task";
9437             }
9438         }
9439     }
9440
9441     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9442         // Remove all tasks with activities in the specified package from the list of recent tasks
9443         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9444             TaskRecord tr = mRecentTasks.get(i);
9445             if (tr.userId != userId) continue;
9446
9447             ComponentName cn = tr.intent.getComponent();
9448             if (cn != null && cn.getPackageName().equals(packageName)) {
9449                 // If the package name matches, remove the task.
9450                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9451             }
9452         }
9453     }
9454
9455     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9456             int userId) {
9457
9458         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9459             TaskRecord tr = mRecentTasks.get(i);
9460             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9461                 continue;
9462             }
9463
9464             ComponentName cn = tr.intent.getComponent();
9465             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9466                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9467             if (sameComponent) {
9468                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9469             }
9470         }
9471     }
9472
9473     /**
9474      * Removes the task with the specified task id.
9475      *
9476      * @param taskId Identifier of the task to be removed.
9477      * @param killProcess Kill any process associated with the task if possible.
9478      * @param removeFromRecents Whether to also remove the task from recents.
9479      * @return Returns true if the given task was found and removed.
9480      */
9481     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9482             boolean removeFromRecents) {
9483         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9484                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9485         if (tr != null) {
9486             tr.removeTaskActivitiesLocked();
9487             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9488             if (tr.isPersistable) {
9489                 notifyTaskPersisterLocked(null, true);
9490             }
9491             return true;
9492         }
9493         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9494         return false;
9495     }
9496
9497     @Override
9498     public void removeStack(int stackId) {
9499         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9500         if (stackId == HOME_STACK_ID) {
9501             throw new IllegalArgumentException("Removing home stack is not allowed.");
9502         }
9503
9504         synchronized (this) {
9505             final long ident = Binder.clearCallingIdentity();
9506             try {
9507                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9508                 if (stack == null) {
9509                     return;
9510                 }
9511                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9512                 for (int i = tasks.size() - 1; i >= 0; i--) {
9513                     removeTaskByIdLocked(
9514                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9515                 }
9516             } finally {
9517                 Binder.restoreCallingIdentity(ident);
9518             }
9519         }
9520     }
9521
9522     @Override
9523     public boolean removeTask(int taskId) {
9524         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9525         synchronized (this) {
9526             final long ident = Binder.clearCallingIdentity();
9527             try {
9528                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9529             } finally {
9530                 Binder.restoreCallingIdentity(ident);
9531             }
9532         }
9533     }
9534
9535     /**
9536      * TODO: Add mController hook
9537      */
9538     @Override
9539     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9540         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9541
9542         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9543         synchronized(this) {
9544             moveTaskToFrontLocked(taskId, flags, bOptions);
9545         }
9546     }
9547
9548     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9549         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9550
9551         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9552                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9553             ActivityOptions.abort(options);
9554             return;
9555         }
9556         final long origId = Binder.clearCallingIdentity();
9557         try {
9558             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9559             if (task == null) {
9560                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9561                 return;
9562             }
9563             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9564                 mStackSupervisor.showLockTaskToast();
9565                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9566                 return;
9567             }
9568             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9569             if (prev != null && prev.isRecentsActivity()) {
9570                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9571             }
9572             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9573                     false /* forceNonResizable */);
9574         } finally {
9575             Binder.restoreCallingIdentity(origId);
9576         }
9577         ActivityOptions.abort(options);
9578     }
9579
9580     /**
9581      * Moves an activity, and all of the other activities within the same task, to the bottom
9582      * of the history stack.  The activity's order within the task is unchanged.
9583      *
9584      * @param token A reference to the activity we wish to move
9585      * @param nonRoot If false then this only works if the activity is the root
9586      *                of a task; if true it will work for any activity in a task.
9587      * @return Returns true if the move completed, false if not.
9588      */
9589     @Override
9590     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9591         enforceNotIsolatedCaller("moveActivityTaskToBack");
9592         synchronized(this) {
9593             final long origId = Binder.clearCallingIdentity();
9594             try {
9595                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9596                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9597                 if (task != null) {
9598                     if (mStackSupervisor.isLockedTask(task)) {
9599                         mStackSupervisor.showLockTaskToast();
9600                         return false;
9601                     }
9602                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9603                 }
9604             } finally {
9605                 Binder.restoreCallingIdentity(origId);
9606             }
9607         }
9608         return false;
9609     }
9610
9611     @Override
9612     public void moveTaskBackwards(int task) {
9613         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9614                 "moveTaskBackwards()");
9615
9616         synchronized(this) {
9617             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9618                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9619                 return;
9620             }
9621             final long origId = Binder.clearCallingIdentity();
9622             moveTaskBackwardsLocked(task);
9623             Binder.restoreCallingIdentity(origId);
9624         }
9625     }
9626
9627     private final void moveTaskBackwardsLocked(int task) {
9628         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9629     }
9630
9631     @Override
9632     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9633             IActivityContainerCallback callback) throws RemoteException {
9634         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9635         synchronized (this) {
9636             if (parentActivityToken == null) {
9637                 throw new IllegalArgumentException("parent token must not be null");
9638             }
9639             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9640             if (r == null) {
9641                 return null;
9642             }
9643             if (callback == null) {
9644                 throw new IllegalArgumentException("callback must not be null");
9645             }
9646             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9647         }
9648     }
9649
9650     @Override
9651     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9652         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9653         synchronized (this) {
9654             mStackSupervisor.deleteActivityContainer(container);
9655         }
9656     }
9657
9658     @Override
9659     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9660         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9661         synchronized (this) {
9662             final int stackId = mStackSupervisor.getNextStackId();
9663             final ActivityStack stack =
9664                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9665             if (stack == null) {
9666                 return null;
9667             }
9668             return stack.mActivityContainer;
9669         }
9670     }
9671
9672     @Override
9673     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9674         synchronized (this) {
9675             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9676             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9677                 return stack.mActivityContainer.getDisplayId();
9678             }
9679             return Display.DEFAULT_DISPLAY;
9680         }
9681     }
9682
9683     @Override
9684     public int getActivityStackId(IBinder token) throws RemoteException {
9685         synchronized (this) {
9686             ActivityStack stack = ActivityRecord.getStackLocked(token);
9687             if (stack == null) {
9688                 return INVALID_STACK_ID;
9689             }
9690             return stack.mStackId;
9691         }
9692     }
9693
9694     @Override
9695     public void exitFreeformMode(IBinder token) throws RemoteException {
9696         synchronized (this) {
9697             long ident = Binder.clearCallingIdentity();
9698             try {
9699                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9700                 if (r == null) {
9701                     throw new IllegalArgumentException(
9702                             "exitFreeformMode: No activity record matching token=" + token);
9703                 }
9704                 final ActivityStack stack = r.getStackLocked(token);
9705                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9706                     throw new IllegalStateException(
9707                             "exitFreeformMode: You can only go fullscreen from freeform.");
9708                 }
9709                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9710                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9711                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9712             } finally {
9713                 Binder.restoreCallingIdentity(ident);
9714             }
9715         }
9716     }
9717
9718     @Override
9719     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9720         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9721         if (stackId == HOME_STACK_ID) {
9722             throw new IllegalArgumentException(
9723                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9724         }
9725         synchronized (this) {
9726             long ident = Binder.clearCallingIdentity();
9727             try {
9728                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9729                         + " to stackId=" + stackId + " toTop=" + toTop);
9730                 if (stackId == DOCKED_STACK_ID) {
9731                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9732                             null /* initialBounds */);
9733                 }
9734                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9735                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9736                 if (result && stackId == DOCKED_STACK_ID) {
9737                     // If task moved to docked stack - show recents if needed.
9738                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9739                             "moveTaskToDockedStack");
9740                 }
9741             } finally {
9742                 Binder.restoreCallingIdentity(ident);
9743             }
9744         }
9745     }
9746
9747     @Override
9748     public void swapDockedAndFullscreenStack() throws RemoteException {
9749         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9750         synchronized (this) {
9751             long ident = Binder.clearCallingIdentity();
9752             try {
9753                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9754                         FULLSCREEN_WORKSPACE_STACK_ID);
9755                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9756                         : null;
9757                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9758                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9759                         : null;
9760                 if (topTask == null || tasks == null || tasks.size() == 0) {
9761                     Slog.w(TAG,
9762                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9763                     return;
9764                 }
9765
9766                 // TODO: App transition
9767                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9768
9769                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9770                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9771                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9772                         ANIMATE, true /* deferResume */);
9773                 final int size = tasks.size();
9774                 for (int i = 0; i < size; i++) {
9775                     final int id = tasks.get(i).taskId;
9776                     if (id == topTask.taskId) {
9777                         continue;
9778                     }
9779                     mStackSupervisor.moveTaskToStackLocked(id,
9780                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9781                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9782                 }
9783
9784                 // Because we deferred the resume, to avoid conflicts with stack switches while
9785                 // resuming, we need to do it after all the tasks are moved.
9786                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9787                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9788
9789                 mWindowManager.executeAppTransition();
9790             } finally {
9791                 Binder.restoreCallingIdentity(ident);
9792             }
9793         }
9794     }
9795
9796     /**
9797      * Moves the input task to the docked stack.
9798      *
9799      * @param taskId Id of task to move.
9800      * @param createMode The mode the docked stack should be created in if it doesn't exist
9801      *                   already. See
9802      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9803      *                   and
9804      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9805      * @param toTop If the task and stack should be moved to the top.
9806      * @param animate Whether we should play an animation for the moving the task
9807      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9808      *                      docked stack. Pass {@code null} to use default bounds.
9809      */
9810     @Override
9811     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9812             Rect initialBounds, boolean moveHomeStackFront) {
9813         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9814         synchronized (this) {
9815             long ident = Binder.clearCallingIdentity();
9816             try {
9817                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9818                         + " to createMode=" + createMode + " toTop=" + toTop);
9819                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9820                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9821                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9822                         animate, DEFER_RESUME);
9823                 if (moved) {
9824                     if (moveHomeStackFront) {
9825                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9826                     }
9827                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9828                 }
9829                 return moved;
9830             } finally {
9831                 Binder.restoreCallingIdentity(ident);
9832             }
9833         }
9834     }
9835
9836     /**
9837      * Moves the top activity in the input stackId to the pinned stack.
9838      *
9839      * @param stackId Id of stack to move the top activity to pinned stack.
9840      * @param bounds Bounds to use for pinned stack.
9841      *
9842      * @return True if the top activity of the input stack was successfully moved to the pinned
9843      *          stack.
9844      */
9845     @Override
9846     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9847         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9848         synchronized (this) {
9849             if (!mSupportsPictureInPicture) {
9850                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9851                         + "Device doesn't support picture-in-pciture mode");
9852             }
9853
9854             long ident = Binder.clearCallingIdentity();
9855             try {
9856                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9857             } finally {
9858                 Binder.restoreCallingIdentity(ident);
9859             }
9860         }
9861     }
9862
9863     @Override
9864     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9865             boolean preserveWindows, boolean animate, int animationDuration) {
9866         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9867         long ident = Binder.clearCallingIdentity();
9868         try {
9869             synchronized (this) {
9870                 if (animate) {
9871                     if (stackId == PINNED_STACK_ID) {
9872                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9873                     } else {
9874                         throw new IllegalArgumentException("Stack: " + stackId
9875                                 + " doesn't support animated resize.");
9876                     }
9877                 } else {
9878                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9879                             null /* tempTaskInsetBounds */, preserveWindows,
9880                             allowResizeInDockedMode, !DEFER_RESUME);
9881                 }
9882             }
9883         } finally {
9884             Binder.restoreCallingIdentity(ident);
9885         }
9886     }
9887
9888     @Override
9889     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9890             Rect tempDockedTaskInsetBounds,
9891             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9892         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9893                 "resizeDockedStack()");
9894         long ident = Binder.clearCallingIdentity();
9895         try {
9896             synchronized (this) {
9897                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9898                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9899                         PRESERVE_WINDOWS);
9900             }
9901         } finally {
9902             Binder.restoreCallingIdentity(ident);
9903         }
9904     }
9905
9906     @Override
9907     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9908         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9909                 "resizePinnedStack()");
9910         final long ident = Binder.clearCallingIdentity();
9911         try {
9912             synchronized (this) {
9913                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9914             }
9915         } finally {
9916             Binder.restoreCallingIdentity(ident);
9917         }
9918     }
9919
9920     @Override
9921     public void positionTaskInStack(int taskId, int stackId, int position) {
9922         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9923         if (stackId == HOME_STACK_ID) {
9924             throw new IllegalArgumentException(
9925                     "positionTaskInStack: Attempt to change the position of task "
9926                     + taskId + " in/to home stack");
9927         }
9928         synchronized (this) {
9929             long ident = Binder.clearCallingIdentity();
9930             try {
9931                 if (DEBUG_STACK) Slog.d(TAG_STACK,
9932                         "positionTaskInStack: positioning task=" + taskId
9933                         + " in stackId=" + stackId + " at position=" + position);
9934                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9935             } finally {
9936                 Binder.restoreCallingIdentity(ident);
9937             }
9938         }
9939     }
9940
9941     @Override
9942     public List<StackInfo> getAllStackInfos() {
9943         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9944         long ident = Binder.clearCallingIdentity();
9945         try {
9946             synchronized (this) {
9947                 return mStackSupervisor.getAllStackInfosLocked();
9948             }
9949         } finally {
9950             Binder.restoreCallingIdentity(ident);
9951         }
9952     }
9953
9954     @Override
9955     public StackInfo getStackInfo(int stackId) {
9956         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9957         long ident = Binder.clearCallingIdentity();
9958         try {
9959             synchronized (this) {
9960                 return mStackSupervisor.getStackInfoLocked(stackId);
9961             }
9962         } finally {
9963             Binder.restoreCallingIdentity(ident);
9964         }
9965     }
9966
9967     @Override
9968     public boolean isInHomeStack(int taskId) {
9969         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9970         long ident = Binder.clearCallingIdentity();
9971         try {
9972             synchronized (this) {
9973                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9974                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9975                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9976             }
9977         } finally {
9978             Binder.restoreCallingIdentity(ident);
9979         }
9980     }
9981
9982     @Override
9983     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9984         synchronized(this) {
9985             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9986         }
9987     }
9988
9989     @Override
9990     public void updateDeviceOwner(String packageName) {
9991         final int callingUid = Binder.getCallingUid();
9992         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9993             throw new SecurityException("updateDeviceOwner called from non-system process");
9994         }
9995         synchronized (this) {
9996             mDeviceOwnerName = packageName;
9997         }
9998     }
9999
10000     @Override
10001     public void updateLockTaskPackages(int userId, String[] packages) {
10002         final int callingUid = Binder.getCallingUid();
10003         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10004             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10005                     "updateLockTaskPackages()");
10006         }
10007         synchronized (this) {
10008             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10009                     Arrays.toString(packages));
10010             mLockTaskPackages.put(userId, packages);
10011             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10012         }
10013     }
10014
10015
10016     void startLockTaskModeLocked(TaskRecord task) {
10017         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10018         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10019             return;
10020         }
10021
10022         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10023         // is initiated by system after the pinning request was shown and locked mode is initiated
10024         // by an authorized app directly
10025         final int callingUid = Binder.getCallingUid();
10026         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10027         long ident = Binder.clearCallingIdentity();
10028         try {
10029             if (!isSystemInitiated) {
10030                 task.mLockTaskUid = callingUid;
10031                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10032                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10033                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10034                     StatusBarManagerInternal statusBarManager =
10035                             LocalServices.getService(StatusBarManagerInternal.class);
10036                     if (statusBarManager != null) {
10037                         statusBarManager.showScreenPinningRequest(task.taskId);
10038                     }
10039                     return;
10040                 }
10041
10042                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10043                 if (stack == null || task != stack.topTask()) {
10044                     throw new IllegalArgumentException("Invalid task, not in foreground");
10045                 }
10046             }
10047             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10048                     "Locking fully");
10049             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10050                     ActivityManager.LOCK_TASK_MODE_PINNED :
10051                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10052                     "startLockTask", true);
10053         } finally {
10054             Binder.restoreCallingIdentity(ident);
10055         }
10056     }
10057
10058     @Override
10059     public void startLockTaskMode(int taskId) {
10060         synchronized (this) {
10061             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10062             if (task != null) {
10063                 startLockTaskModeLocked(task);
10064             }
10065         }
10066     }
10067
10068     @Override
10069     public void startLockTaskMode(IBinder token) {
10070         synchronized (this) {
10071             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10072             if (r == null) {
10073                 return;
10074             }
10075             final TaskRecord task = r.task;
10076             if (task != null) {
10077                 startLockTaskModeLocked(task);
10078             }
10079         }
10080     }
10081
10082     @Override
10083     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10084         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10085         // This makes inner call to look as if it was initiated by system.
10086         long ident = Binder.clearCallingIdentity();
10087         try {
10088             synchronized (this) {
10089                 startLockTaskMode(taskId);
10090             }
10091         } finally {
10092             Binder.restoreCallingIdentity(ident);
10093         }
10094     }
10095
10096     @Override
10097     public void stopLockTaskMode() {
10098         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10099         if (lockTask == null) {
10100             // Our work here is done.
10101             return;
10102         }
10103
10104         final int callingUid = Binder.getCallingUid();
10105         final int lockTaskUid = lockTask.mLockTaskUid;
10106         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10107         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10108             // Done.
10109             return;
10110         } else {
10111             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10112             // It is possible lockTaskMode was started by the system process because
10113             // android:lockTaskMode is set to a locking value in the application manifest
10114             // instead of the app calling startLockTaskMode. In this case
10115             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10116             // {@link TaskRecord.effectiveUid} instead. Also caller with
10117             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10118             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10119                     && callingUid != lockTaskUid
10120                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10121                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10122                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10123             }
10124         }
10125         long ident = Binder.clearCallingIdentity();
10126         try {
10127             Log.d(TAG, "stopLockTaskMode");
10128             // Stop lock task
10129             synchronized (this) {
10130                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10131                         "stopLockTask", true);
10132             }
10133             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10134             if (tm != null) {
10135                 tm.showInCallScreen(false);
10136             }
10137         } finally {
10138             Binder.restoreCallingIdentity(ident);
10139         }
10140     }
10141
10142     /**
10143      * This API should be called by SystemUI only when user perform certain action to dismiss
10144      * lock task mode. We should only dismiss pinned lock task mode in this case.
10145      */
10146     @Override
10147     public void stopSystemLockTaskMode() throws RemoteException {
10148         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10149             stopLockTaskMode();
10150         } else {
10151             mStackSupervisor.showLockTaskToast();
10152         }
10153     }
10154
10155     @Override
10156     public boolean isInLockTaskMode() {
10157         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10158     }
10159
10160     @Override
10161     public int getLockTaskModeState() {
10162         synchronized (this) {
10163             return mStackSupervisor.getLockTaskModeState();
10164         }
10165     }
10166
10167     @Override
10168     public void showLockTaskEscapeMessage(IBinder token) {
10169         synchronized (this) {
10170             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10171             if (r == null) {
10172                 return;
10173             }
10174             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10175         }
10176     }
10177
10178     // =========================================================
10179     // CONTENT PROVIDERS
10180     // =========================================================
10181
10182     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10183         List<ProviderInfo> providers = null;
10184         try {
10185             providers = AppGlobals.getPackageManager()
10186                     .queryContentProviders(app.processName, app.uid,
10187                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10188                                     | MATCH_DEBUG_TRIAGED_MISSING)
10189                     .getList();
10190         } catch (RemoteException ex) {
10191         }
10192         if (DEBUG_MU) Slog.v(TAG_MU,
10193                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10194         int userId = app.userId;
10195         if (providers != null) {
10196             int N = providers.size();
10197             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10198             for (int i=0; i<N; i++) {
10199                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10200                 ProviderInfo cpi =
10201                     (ProviderInfo)providers.get(i);
10202                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10203                         cpi.name, cpi.flags);
10204                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10205                     // This is a singleton provider, but a user besides the
10206                     // default user is asking to initialize a process it runs
10207                     // in...  well, no, it doesn't actually run in this process,
10208                     // it runs in the process of the default user.  Get rid of it.
10209                     providers.remove(i);
10210                     N--;
10211                     i--;
10212                     continue;
10213                 }
10214
10215                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10216                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10217                 if (cpr == null) {
10218                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10219                     mProviderMap.putProviderByClass(comp, cpr);
10220                 }
10221                 if (DEBUG_MU) Slog.v(TAG_MU,
10222                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10223                 app.pubProviders.put(cpi.name, cpr);
10224                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10225                     // Don't add this if it is a platform component that is marked
10226                     // to run in multiple processes, because this is actually
10227                     // part of the framework so doesn't make sense to track as a
10228                     // separate apk in the process.
10229                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10230                             mProcessStats);
10231                 }
10232                 notifyPackageUse(cpi.applicationInfo.packageName,
10233                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10234             }
10235         }
10236         return providers;
10237     }
10238
10239     /**
10240      * Check if {@link ProcessRecord} has a possible chance at accessing the
10241      * given {@link ProviderInfo}. Final permission checking is always done
10242      * in {@link ContentProvider}.
10243      */
10244     private final String checkContentProviderPermissionLocked(
10245             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10246         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10247         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10248         boolean checkedGrants = false;
10249         if (checkUser) {
10250             // Looking for cross-user grants before enforcing the typical cross-users permissions
10251             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10252             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10253                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10254                     return null;
10255                 }
10256                 checkedGrants = true;
10257             }
10258             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10259                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10260             if (userId != tmpTargetUserId) {
10261                 // When we actually went to determine the final targer user ID, this ended
10262                 // up different than our initial check for the authority.  This is because
10263                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10264                 // SELF.  So we need to re-check the grants again.
10265                 checkedGrants = false;
10266             }
10267         }
10268         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10269                 cpi.applicationInfo.uid, cpi.exported)
10270                 == PackageManager.PERMISSION_GRANTED) {
10271             return null;
10272         }
10273         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10274                 cpi.applicationInfo.uid, cpi.exported)
10275                 == PackageManager.PERMISSION_GRANTED) {
10276             return null;
10277         }
10278
10279         PathPermission[] pps = cpi.pathPermissions;
10280         if (pps != null) {
10281             int i = pps.length;
10282             while (i > 0) {
10283                 i--;
10284                 PathPermission pp = pps[i];
10285                 String pprperm = pp.getReadPermission();
10286                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10287                         cpi.applicationInfo.uid, cpi.exported)
10288                         == PackageManager.PERMISSION_GRANTED) {
10289                     return null;
10290                 }
10291                 String ppwperm = pp.getWritePermission();
10292                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10293                         cpi.applicationInfo.uid, cpi.exported)
10294                         == PackageManager.PERMISSION_GRANTED) {
10295                     return null;
10296                 }
10297             }
10298         }
10299         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10300             return null;
10301         }
10302
10303         String msg;
10304         if (!cpi.exported) {
10305             msg = "Permission Denial: opening provider " + cpi.name
10306                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10307                     + ", uid=" + callingUid + ") that is not exported from uid "
10308                     + cpi.applicationInfo.uid;
10309         } else {
10310             msg = "Permission Denial: opening provider " + cpi.name
10311                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10312                     + ", uid=" + callingUid + ") requires "
10313                     + cpi.readPermission + " or " + cpi.writePermission;
10314         }
10315         Slog.w(TAG, msg);
10316         return msg;
10317     }
10318
10319     /**
10320      * Returns if the ContentProvider has granted a uri to callingUid
10321      */
10322     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10323         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10324         if (perms != null) {
10325             for (int i=perms.size()-1; i>=0; i--) {
10326                 GrantUri grantUri = perms.keyAt(i);
10327                 if (grantUri.sourceUserId == userId || !checkUser) {
10328                     if (matchesProvider(grantUri.uri, cpi)) {
10329                         return true;
10330                     }
10331                 }
10332             }
10333         }
10334         return false;
10335     }
10336
10337     /**
10338      * Returns true if the uri authority is one of the authorities specified in the provider.
10339      */
10340     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10341         String uriAuth = uri.getAuthority();
10342         String cpiAuth = cpi.authority;
10343         if (cpiAuth.indexOf(';') == -1) {
10344             return cpiAuth.equals(uriAuth);
10345         }
10346         String[] cpiAuths = cpiAuth.split(";");
10347         int length = cpiAuths.length;
10348         for (int i = 0; i < length; i++) {
10349             if (cpiAuths[i].equals(uriAuth)) return true;
10350         }
10351         return false;
10352     }
10353
10354     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10355             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10356         if (r != null) {
10357             for (int i=0; i<r.conProviders.size(); i++) {
10358                 ContentProviderConnection conn = r.conProviders.get(i);
10359                 if (conn.provider == cpr) {
10360                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10361                             "Adding provider requested by "
10362                             + r.processName + " from process "
10363                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10364                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10365                     if (stable) {
10366                         conn.stableCount++;
10367                         conn.numStableIncs++;
10368                     } else {
10369                         conn.unstableCount++;
10370                         conn.numUnstableIncs++;
10371                     }
10372                     return conn;
10373                 }
10374             }
10375             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10376             if (stable) {
10377                 conn.stableCount = 1;
10378                 conn.numStableIncs = 1;
10379             } else {
10380                 conn.unstableCount = 1;
10381                 conn.numUnstableIncs = 1;
10382             }
10383             cpr.connections.add(conn);
10384             r.conProviders.add(conn);
10385             startAssociationLocked(r.uid, r.processName, r.curProcState,
10386                     cpr.uid, cpr.name, cpr.info.processName);
10387             return conn;
10388         }
10389         cpr.addExternalProcessHandleLocked(externalProcessToken);
10390         return null;
10391     }
10392
10393     boolean decProviderCountLocked(ContentProviderConnection conn,
10394             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10395         if (conn != null) {
10396             cpr = conn.provider;
10397             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10398                     "Removing provider requested by "
10399                     + conn.client.processName + " from process "
10400                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10401                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10402             if (stable) {
10403                 conn.stableCount--;
10404             } else {
10405                 conn.unstableCount--;
10406             }
10407             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10408                 cpr.connections.remove(conn);
10409                 conn.client.conProviders.remove(conn);
10410                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10411                     // The client is more important than last activity -- note the time this
10412                     // is happening, so we keep the old provider process around a bit as last
10413                     // activity to avoid thrashing it.
10414                     if (cpr.proc != null) {
10415                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10416                     }
10417                 }
10418                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10419                 return true;
10420             }
10421             return false;
10422         }
10423         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10424         return false;
10425     }
10426
10427     private void checkTime(long startTime, String where) {
10428         long now = SystemClock.uptimeMillis();
10429         if ((now-startTime) > 50) {
10430             // If we are taking more than 50ms, log about it.
10431             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10432         }
10433     }
10434
10435     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10436             String name, IBinder token, boolean stable, int userId) {
10437         ContentProviderRecord cpr;
10438         ContentProviderConnection conn = null;
10439         ProviderInfo cpi = null;
10440
10441         synchronized(this) {
10442             long startTime = SystemClock.uptimeMillis();
10443
10444             ProcessRecord r = null;
10445             if (caller != null) {
10446                 r = getRecordForAppLocked(caller);
10447                 if (r == null) {
10448                     throw new SecurityException(
10449                             "Unable to find app for caller " + caller
10450                           + " (pid=" + Binder.getCallingPid()
10451                           + ") when getting content provider " + name);
10452                 }
10453             }
10454
10455             boolean checkCrossUser = true;
10456
10457             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10458
10459             // First check if this content provider has been published...
10460             cpr = mProviderMap.getProviderByName(name, userId);
10461             // If that didn't work, check if it exists for user 0 and then
10462             // verify that it's a singleton provider before using it.
10463             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10464                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10465                 if (cpr != null) {
10466                     cpi = cpr.info;
10467                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10468                             cpi.name, cpi.flags)
10469                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10470                         userId = UserHandle.USER_SYSTEM;
10471                         checkCrossUser = false;
10472                     } else {
10473                         cpr = null;
10474                         cpi = null;
10475                     }
10476                 }
10477             }
10478
10479             boolean providerRunning = cpr != null;
10480             if (providerRunning) {
10481                 cpi = cpr.info;
10482                 String msg;
10483                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10484                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10485                         != null) {
10486                     throw new SecurityException(msg);
10487                 }
10488                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10489
10490                 if (r != null && cpr.canRunHere(r)) {
10491                     // This provider has been published or is in the process
10492                     // of being published...  but it is also allowed to run
10493                     // in the caller's process, so don't make a connection
10494                     // and just let the caller instantiate its own instance.
10495                     ContentProviderHolder holder = cpr.newHolder(null);
10496                     // don't give caller the provider object, it needs
10497                     // to make its own.
10498                     holder.provider = null;
10499                     return holder;
10500                 }
10501
10502                 final long origId = Binder.clearCallingIdentity();
10503
10504                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10505
10506                 // In this case the provider instance already exists, so we can
10507                 // return it right away.
10508                 conn = incProviderCountLocked(r, cpr, token, stable);
10509                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10510                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10511                         // If this is a perceptible app accessing the provider,
10512                         // make sure to count it as being accessed and thus
10513                         // back up on the LRU list.  This is good because
10514                         // content providers are often expensive to start.
10515                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10516                         updateLruProcessLocked(cpr.proc, false, null);
10517                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10518                     }
10519                 }
10520
10521                 if (cpr.proc != null) {
10522                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10523                     boolean success = updateOomAdjLocked(cpr.proc);
10524                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10525                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10526                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10527                     // NOTE: there is still a race here where a signal could be
10528                     // pending on the process even though we managed to update its
10529                     // adj level.  Not sure what to do about this, but at least
10530                     // the race is now smaller.
10531                     if (!success) {
10532                         // Uh oh...  it looks like the provider's process
10533                         // has been killed on us.  We need to wait for a new
10534                         // process to be started, and make sure its death
10535                         // doesn't kill our process.
10536                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10537                                 + " is crashing; detaching " + r);
10538                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10539                         checkTime(startTime, "getContentProviderImpl: before appDied");
10540                         appDiedLocked(cpr.proc);
10541                         checkTime(startTime, "getContentProviderImpl: after appDied");
10542                         if (!lastRef) {
10543                             // This wasn't the last ref our process had on
10544                             // the provider...  we have now been killed, bail.
10545                             return null;
10546                         }
10547                         providerRunning = false;
10548                         conn = null;
10549                     }
10550                 }
10551
10552                 Binder.restoreCallingIdentity(origId);
10553             }
10554
10555             if (!providerRunning) {
10556                 try {
10557                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10558                     cpi = AppGlobals.getPackageManager().
10559                         resolveContentProvider(name,
10560                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10561                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10562                 } catch (RemoteException ex) {
10563                 }
10564                 if (cpi == null) {
10565                     return null;
10566                 }
10567                 // If the provider is a singleton AND
10568                 // (it's a call within the same user || the provider is a
10569                 // privileged app)
10570                 // Then allow connecting to the singleton provider
10571                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10572                         cpi.name, cpi.flags)
10573                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10574                 if (singleton) {
10575                     userId = UserHandle.USER_SYSTEM;
10576                 }
10577                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10578                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10579
10580                 String msg;
10581                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10582                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10583                         != null) {
10584                     throw new SecurityException(msg);
10585                 }
10586                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10587
10588                 if (!mProcessesReady
10589                         && !cpi.processName.equals("system")) {
10590                     // If this content provider does not run in the system
10591                     // process, and the system is not yet ready to run other
10592                     // processes, then fail fast instead of hanging.
10593                     throw new IllegalArgumentException(
10594                             "Attempt to launch content provider before system ready");
10595                 }
10596
10597                 // Make sure that the user who owns this provider is running.  If not,
10598                 // we don't want to allow it to run.
10599                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10600                     Slog.w(TAG, "Unable to launch app "
10601                             + cpi.applicationInfo.packageName + "/"
10602                             + cpi.applicationInfo.uid + " for provider "
10603                             + name + ": user " + userId + " is stopped");
10604                     return null;
10605                 }
10606
10607                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10608                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10609                 cpr = mProviderMap.getProviderByClass(comp, userId);
10610                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10611                 final boolean firstClass = cpr == null;
10612                 if (firstClass) {
10613                     final long ident = Binder.clearCallingIdentity();
10614
10615                     // If permissions need a review before any of the app components can run,
10616                     // we return no provider and launch a review activity if the calling app
10617                     // is in the foreground.
10618                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10619                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10620                             return null;
10621                         }
10622                     }
10623
10624                     try {
10625                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10626                         ApplicationInfo ai =
10627                             AppGlobals.getPackageManager().
10628                                 getApplicationInfo(
10629                                         cpi.applicationInfo.packageName,
10630                                         STOCK_PM_FLAGS, userId);
10631                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10632                         if (ai == null) {
10633                             Slog.w(TAG, "No package info for content provider "
10634                                     + cpi.name);
10635                             return null;
10636                         }
10637                         ai = getAppInfoForUser(ai, userId);
10638                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10639                     } catch (RemoteException ex) {
10640                         // pm is in same process, this will never happen.
10641                     } finally {
10642                         Binder.restoreCallingIdentity(ident);
10643                     }
10644                 }
10645
10646                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10647
10648                 if (r != null && cpr.canRunHere(r)) {
10649                     // If this is a multiprocess provider, then just return its
10650                     // info and allow the caller to instantiate it.  Only do
10651                     // this if the provider is the same user as the caller's
10652                     // process, or can run as root (so can be in any process).
10653                     return cpr.newHolder(null);
10654                 }
10655
10656                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10657                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10658                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10659
10660                 // This is single process, and our app is now connecting to it.
10661                 // See if we are already in the process of launching this
10662                 // provider.
10663                 final int N = mLaunchingProviders.size();
10664                 int i;
10665                 for (i = 0; i < N; i++) {
10666                     if (mLaunchingProviders.get(i) == cpr) {
10667                         break;
10668                     }
10669                 }
10670
10671                 // If the provider is not already being launched, then get it
10672                 // started.
10673                 if (i >= N) {
10674                     final long origId = Binder.clearCallingIdentity();
10675
10676                     try {
10677                         // Content provider is now in use, its package can't be stopped.
10678                         try {
10679                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10680                             AppGlobals.getPackageManager().setPackageStoppedState(
10681                                     cpr.appInfo.packageName, false, userId);
10682                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10683                         } catch (RemoteException e) {
10684                         } catch (IllegalArgumentException e) {
10685                             Slog.w(TAG, "Failed trying to unstop package "
10686                                     + cpr.appInfo.packageName + ": " + e);
10687                         }
10688
10689                         // Use existing process if already started
10690                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10691                         ProcessRecord proc = getProcessRecordLocked(
10692                                 cpi.processName, cpr.appInfo.uid, false);
10693                         if (proc != null && proc.thread != null) {
10694                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10695                                     "Installing in existing process " + proc);
10696                             if (!proc.pubProviders.containsKey(cpi.name)) {
10697                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10698                                 proc.pubProviders.put(cpi.name, cpr);
10699                                 try {
10700                                     proc.thread.scheduleInstallProvider(cpi);
10701                                 } catch (RemoteException e) {
10702                                 }
10703                             }
10704                         } else {
10705                             checkTime(startTime, "getContentProviderImpl: before start process");
10706                             proc = startProcessLocked(cpi.processName,
10707                                     cpr.appInfo, false, 0, "content provider",
10708                                     new ComponentName(cpi.applicationInfo.packageName,
10709                                             cpi.name), false, false, false);
10710                             checkTime(startTime, "getContentProviderImpl: after start process");
10711                             if (proc == null) {
10712                                 Slog.w(TAG, "Unable to launch app "
10713                                         + cpi.applicationInfo.packageName + "/"
10714                                         + cpi.applicationInfo.uid + " for provider "
10715                                         + name + ": process is bad");
10716                                 return null;
10717                             }
10718                         }
10719                         cpr.launchingApp = proc;
10720                         mLaunchingProviders.add(cpr);
10721                     } finally {
10722                         Binder.restoreCallingIdentity(origId);
10723                     }
10724                 }
10725
10726                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10727
10728                 // Make sure the provider is published (the same provider class
10729                 // may be published under multiple names).
10730                 if (firstClass) {
10731                     mProviderMap.putProviderByClass(comp, cpr);
10732                 }
10733
10734                 mProviderMap.putProviderByName(name, cpr);
10735                 conn = incProviderCountLocked(r, cpr, token, stable);
10736                 if (conn != null) {
10737                     conn.waiting = true;
10738                 }
10739             }
10740             checkTime(startTime, "getContentProviderImpl: done!");
10741         }
10742
10743         // Wait for the provider to be published...
10744         synchronized (cpr) {
10745             while (cpr.provider == null) {
10746                 if (cpr.launchingApp == null) {
10747                     Slog.w(TAG, "Unable to launch app "
10748                             + cpi.applicationInfo.packageName + "/"
10749                             + cpi.applicationInfo.uid + " for provider "
10750                             + name + ": launching app became null");
10751                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10752                             UserHandle.getUserId(cpi.applicationInfo.uid),
10753                             cpi.applicationInfo.packageName,
10754                             cpi.applicationInfo.uid, name);
10755                     return null;
10756                 }
10757                 try {
10758                     if (DEBUG_MU) Slog.v(TAG_MU,
10759                             "Waiting to start provider " + cpr
10760                             + " launchingApp=" + cpr.launchingApp);
10761                     if (conn != null) {
10762                         conn.waiting = true;
10763                     }
10764                     cpr.wait();
10765                 } catch (InterruptedException ex) {
10766                 } finally {
10767                     if (conn != null) {
10768                         conn.waiting = false;
10769                     }
10770                 }
10771             }
10772         }
10773         return cpr != null ? cpr.newHolder(conn) : null;
10774     }
10775
10776     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10777             ProcessRecord r, final int userId) {
10778         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10779                 cpi.packageName, userId)) {
10780
10781             final boolean callerForeground = r == null || r.setSchedGroup
10782                     != ProcessList.SCHED_GROUP_BACKGROUND;
10783
10784             // Show a permission review UI only for starting from a foreground app
10785             if (!callerForeground) {
10786                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10787                         + cpi.packageName + " requires a permissions review");
10788                 return false;
10789             }
10790
10791             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10792             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10793                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10794             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10795
10796             if (DEBUG_PERMISSIONS_REVIEW) {
10797                 Slog.i(TAG, "u" + userId + " Launching permission review "
10798                         + "for package " + cpi.packageName);
10799             }
10800
10801             final UserHandle userHandle = new UserHandle(userId);
10802             mHandler.post(new Runnable() {
10803                 @Override
10804                 public void run() {
10805                     mContext.startActivityAsUser(intent, userHandle);
10806                 }
10807             });
10808
10809             return false;
10810         }
10811
10812         return true;
10813     }
10814
10815     PackageManagerInternal getPackageManagerInternalLocked() {
10816         if (mPackageManagerInt == null) {
10817             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10818         }
10819         return mPackageManagerInt;
10820     }
10821
10822     @Override
10823     public final ContentProviderHolder getContentProvider(
10824             IApplicationThread caller, String name, int userId, boolean stable) {
10825         enforceNotIsolatedCaller("getContentProvider");
10826         if (caller == null) {
10827             String msg = "null IApplicationThread when getting content provider "
10828                     + name;
10829             Slog.w(TAG, msg);
10830             throw new SecurityException(msg);
10831         }
10832         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10833         // with cross-user grant.
10834         return getContentProviderImpl(caller, name, null, stable, userId);
10835     }
10836
10837     public ContentProviderHolder getContentProviderExternal(
10838             String name, int userId, IBinder token) {
10839         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10840             "Do not have permission in call getContentProviderExternal()");
10841         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10842                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10843         return getContentProviderExternalUnchecked(name, token, userId);
10844     }
10845
10846     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10847             IBinder token, int userId) {
10848         return getContentProviderImpl(null, name, token, true, userId);
10849     }
10850
10851     /**
10852      * Drop a content provider from a ProcessRecord's bookkeeping
10853      */
10854     public void removeContentProvider(IBinder connection, boolean stable) {
10855         enforceNotIsolatedCaller("removeContentProvider");
10856         long ident = Binder.clearCallingIdentity();
10857         try {
10858             synchronized (this) {
10859                 ContentProviderConnection conn;
10860                 try {
10861                     conn = (ContentProviderConnection)connection;
10862                 } catch (ClassCastException e) {
10863                     String msg ="removeContentProvider: " + connection
10864                             + " not a ContentProviderConnection";
10865                     Slog.w(TAG, msg);
10866                     throw new IllegalArgumentException(msg);
10867                 }
10868                 if (conn == null) {
10869                     throw new NullPointerException("connection is null");
10870                 }
10871                 if (decProviderCountLocked(conn, null, null, stable)) {
10872                     updateOomAdjLocked();
10873                 }
10874             }
10875         } finally {
10876             Binder.restoreCallingIdentity(ident);
10877         }
10878     }
10879
10880     public void removeContentProviderExternal(String name, IBinder token) {
10881         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10882             "Do not have permission in call removeContentProviderExternal()");
10883         int userId = UserHandle.getCallingUserId();
10884         long ident = Binder.clearCallingIdentity();
10885         try {
10886             removeContentProviderExternalUnchecked(name, token, userId);
10887         } finally {
10888             Binder.restoreCallingIdentity(ident);
10889         }
10890     }
10891
10892     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10893         synchronized (this) {
10894             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10895             if(cpr == null) {
10896                 //remove from mProvidersByClass
10897                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10898                 return;
10899             }
10900
10901             //update content provider record entry info
10902             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10903             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10904             if (localCpr.hasExternalProcessHandles()) {
10905                 if (localCpr.removeExternalProcessHandleLocked(token)) {
10906                     updateOomAdjLocked();
10907                 } else {
10908                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10909                             + " with no external reference for token: "
10910                             + token + ".");
10911                 }
10912             } else {
10913                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10914                         + " with no external references.");
10915             }
10916         }
10917     }
10918
10919     public final void publishContentProviders(IApplicationThread caller,
10920             List<ContentProviderHolder> providers) {
10921         if (providers == null) {
10922             return;
10923         }
10924
10925         enforceNotIsolatedCaller("publishContentProviders");
10926         synchronized (this) {
10927             final ProcessRecord r = getRecordForAppLocked(caller);
10928             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10929             if (r == null) {
10930                 throw new SecurityException(
10931                         "Unable to find app for caller " + caller
10932                       + " (pid=" + Binder.getCallingPid()
10933                       + ") when publishing content providers");
10934             }
10935
10936             final long origId = Binder.clearCallingIdentity();
10937
10938             final int N = providers.size();
10939             for (int i = 0; i < N; i++) {
10940                 ContentProviderHolder src = providers.get(i);
10941                 if (src == null || src.info == null || src.provider == null) {
10942                     continue;
10943                 }
10944                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10945                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10946                 if (dst != null) {
10947                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10948                     mProviderMap.putProviderByClass(comp, dst);
10949                     String names[] = dst.info.authority.split(";");
10950                     for (int j = 0; j < names.length; j++) {
10951                         mProviderMap.putProviderByName(names[j], dst);
10952                     }
10953
10954                     int launchingCount = mLaunchingProviders.size();
10955                     int j;
10956                     boolean wasInLaunchingProviders = false;
10957                     for (j = 0; j < launchingCount; j++) {
10958                         if (mLaunchingProviders.get(j) == dst) {
10959                             mLaunchingProviders.remove(j);
10960                             wasInLaunchingProviders = true;
10961                             j--;
10962                             launchingCount--;
10963                         }
10964                     }
10965                     if (wasInLaunchingProviders) {
10966                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10967                     }
10968                     synchronized (dst) {
10969                         dst.provider = src.provider;
10970                         dst.proc = r;
10971                         dst.notifyAll();
10972                     }
10973                     updateOomAdjLocked(r);
10974                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10975                             src.info.authority);
10976                 }
10977             }
10978
10979             Binder.restoreCallingIdentity(origId);
10980         }
10981     }
10982
10983     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10984         ContentProviderConnection conn;
10985         try {
10986             conn = (ContentProviderConnection)connection;
10987         } catch (ClassCastException e) {
10988             String msg ="refContentProvider: " + connection
10989                     + " not a ContentProviderConnection";
10990             Slog.w(TAG, msg);
10991             throw new IllegalArgumentException(msg);
10992         }
10993         if (conn == null) {
10994             throw new NullPointerException("connection is null");
10995         }
10996
10997         synchronized (this) {
10998             if (stable > 0) {
10999                 conn.numStableIncs += stable;
11000             }
11001             stable = conn.stableCount + stable;
11002             if (stable < 0) {
11003                 throw new IllegalStateException("stableCount < 0: " + stable);
11004             }
11005
11006             if (unstable > 0) {
11007                 conn.numUnstableIncs += unstable;
11008             }
11009             unstable = conn.unstableCount + unstable;
11010             if (unstable < 0) {
11011                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11012             }
11013
11014             if ((stable+unstable) <= 0) {
11015                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11016                         + stable + " unstable=" + unstable);
11017             }
11018             conn.stableCount = stable;
11019             conn.unstableCount = unstable;
11020             return !conn.dead;
11021         }
11022     }
11023
11024     public void unstableProviderDied(IBinder connection) {
11025         ContentProviderConnection conn;
11026         try {
11027             conn = (ContentProviderConnection)connection;
11028         } catch (ClassCastException e) {
11029             String msg ="refContentProvider: " + connection
11030                     + " not a ContentProviderConnection";
11031             Slog.w(TAG, msg);
11032             throw new IllegalArgumentException(msg);
11033         }
11034         if (conn == null) {
11035             throw new NullPointerException("connection is null");
11036         }
11037
11038         // Safely retrieve the content provider associated with the connection.
11039         IContentProvider provider;
11040         synchronized (this) {
11041             provider = conn.provider.provider;
11042         }
11043
11044         if (provider == null) {
11045             // Um, yeah, we're way ahead of you.
11046             return;
11047         }
11048
11049         // Make sure the caller is being honest with us.
11050         if (provider.asBinder().pingBinder()) {
11051             // Er, no, still looks good to us.
11052             synchronized (this) {
11053                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11054                         + " says " + conn + " died, but we don't agree");
11055                 return;
11056             }
11057         }
11058
11059         // Well look at that!  It's dead!
11060         synchronized (this) {
11061             if (conn.provider.provider != provider) {
11062                 // But something changed...  good enough.
11063                 return;
11064             }
11065
11066             ProcessRecord proc = conn.provider.proc;
11067             if (proc == null || proc.thread == null) {
11068                 // Seems like the process is already cleaned up.
11069                 return;
11070             }
11071
11072             // As far as we're concerned, this is just like receiving a
11073             // death notification...  just a bit prematurely.
11074             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11075                     + ") early provider death");
11076             final long ident = Binder.clearCallingIdentity();
11077             try {
11078                 appDiedLocked(proc);
11079             } finally {
11080                 Binder.restoreCallingIdentity(ident);
11081             }
11082         }
11083     }
11084
11085     @Override
11086     public void appNotRespondingViaProvider(IBinder connection) {
11087         enforceCallingPermission(
11088                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11089
11090         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11091         if (conn == null) {
11092             Slog.w(TAG, "ContentProviderConnection is null");
11093             return;
11094         }
11095
11096         final ProcessRecord host = conn.provider.proc;
11097         if (host == null) {
11098             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11099             return;
11100         }
11101
11102         mHandler.post(new Runnable() {
11103             @Override
11104             public void run() {
11105                 mAppErrors.appNotResponding(host, null, null, false,
11106                         "ContentProvider not responding");
11107             }
11108         });
11109     }
11110
11111     public final void installSystemProviders() {
11112         List<ProviderInfo> providers;
11113         synchronized (this) {
11114             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11115             providers = generateApplicationProvidersLocked(app);
11116             if (providers != null) {
11117                 for (int i=providers.size()-1; i>=0; i--) {
11118                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11119                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11120                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11121                                 + ": not system .apk");
11122                         providers.remove(i);
11123                     }
11124                 }
11125             }
11126         }
11127         if (providers != null) {
11128             mSystemThread.installSystemProviders(providers);
11129         }
11130
11131         mCoreSettingsObserver = new CoreSettingsObserver(this);
11132         mFontScaleSettingObserver = new FontScaleSettingObserver();
11133
11134         //mUsageStatsService.monitorPackages();
11135     }
11136
11137     private void startPersistentApps(int matchFlags) {
11138         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11139
11140         synchronized (this) {
11141             try {
11142                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11143                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11144                 for (ApplicationInfo app : apps) {
11145                     if (!"android".equals(app.packageName)) {
11146                         addAppLocked(app, false, null /* ABI override */);
11147                     }
11148                 }
11149             } catch (RemoteException ex) {
11150             }
11151         }
11152     }
11153
11154     /**
11155      * When a user is unlocked, we need to install encryption-unaware providers
11156      * belonging to any running apps.
11157      */
11158     private void installEncryptionUnawareProviders(int userId) {
11159         // We're only interested in providers that are encryption unaware, and
11160         // we don't care about uninstalled apps, since there's no way they're
11161         // running at this point.
11162         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11163
11164         synchronized (this) {
11165             final int NP = mProcessNames.getMap().size();
11166             for (int ip = 0; ip < NP; ip++) {
11167                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11168                 final int NA = apps.size();
11169                 for (int ia = 0; ia < NA; ia++) {
11170                     final ProcessRecord app = apps.valueAt(ia);
11171                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11172
11173                     final int NG = app.pkgList.size();
11174                     for (int ig = 0; ig < NG; ig++) {
11175                         try {
11176                             final String pkgName = app.pkgList.keyAt(ig);
11177                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11178                                     .getPackageInfo(pkgName, matchFlags, userId);
11179                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11180                                 for (ProviderInfo pi : pkgInfo.providers) {
11181                                     // TODO: keep in sync with generateApplicationProvidersLocked
11182                                     final boolean processMatch = Objects.equals(pi.processName,
11183                                             app.processName) || pi.multiprocess;
11184                                     final boolean userMatch = isSingleton(pi.processName,
11185                                             pi.applicationInfo, pi.name, pi.flags)
11186                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11187                                     if (processMatch && userMatch) {
11188                                         Log.v(TAG, "Installing " + pi);
11189                                         app.thread.scheduleInstallProvider(pi);
11190                                     } else {
11191                                         Log.v(TAG, "Skipping " + pi);
11192                                     }
11193                                 }
11194                             }
11195                         } catch (RemoteException ignored) {
11196                         }
11197                     }
11198                 }
11199             }
11200         }
11201     }
11202
11203     /**
11204      * Allows apps to retrieve the MIME type of a URI.
11205      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11206      * users, then it does not need permission to access the ContentProvider.
11207      * Either, it needs cross-user uri grants.
11208      *
11209      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11210      *
11211      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11212      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11213      */
11214     public String getProviderMimeType(Uri uri, int userId) {
11215         enforceNotIsolatedCaller("getProviderMimeType");
11216         final String name = uri.getAuthority();
11217         int callingUid = Binder.getCallingUid();
11218         int callingPid = Binder.getCallingPid();
11219         long ident = 0;
11220         boolean clearedIdentity = false;
11221         synchronized (this) {
11222             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11223         }
11224         if (canClearIdentity(callingPid, callingUid, userId)) {
11225             clearedIdentity = true;
11226             ident = Binder.clearCallingIdentity();
11227         }
11228         ContentProviderHolder holder = null;
11229         try {
11230             holder = getContentProviderExternalUnchecked(name, null, userId);
11231             if (holder != null) {
11232                 return holder.provider.getType(uri);
11233             }
11234         } catch (RemoteException e) {
11235             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11236             return null;
11237         } finally {
11238             // We need to clear the identity to call removeContentProviderExternalUnchecked
11239             if (!clearedIdentity) {
11240                 ident = Binder.clearCallingIdentity();
11241             }
11242             try {
11243                 if (holder != null) {
11244                     removeContentProviderExternalUnchecked(name, null, userId);
11245                 }
11246             } finally {
11247                 Binder.restoreCallingIdentity(ident);
11248             }
11249         }
11250
11251         return null;
11252     }
11253
11254     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11255         if (UserHandle.getUserId(callingUid) == userId) {
11256             return true;
11257         }
11258         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11259                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11260                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11261                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11262                 return true;
11263         }
11264         return false;
11265     }
11266
11267     // =========================================================
11268     // GLOBAL MANAGEMENT
11269     // =========================================================
11270
11271     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11272             boolean isolated, int isolatedUid) {
11273         String proc = customProcess != null ? customProcess : info.processName;
11274         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11275         final int userId = UserHandle.getUserId(info.uid);
11276         int uid = info.uid;
11277         if (isolated) {
11278             if (isolatedUid == 0) {
11279                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11280                 while (true) {
11281                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11282                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11283                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11284                     }
11285                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11286                     mNextIsolatedProcessUid++;
11287                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11288                         // No process for this uid, use it.
11289                         break;
11290                     }
11291                     stepsLeft--;
11292                     if (stepsLeft <= 0) {
11293                         return null;
11294                     }
11295                 }
11296             } else {
11297                 // Special case for startIsolatedProcess (internal only), where
11298                 // the uid of the isolated process is specified by the caller.
11299                 uid = isolatedUid;
11300             }
11301         }
11302         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11303         if (!mBooted && !mBooting
11304                 && userId == UserHandle.USER_SYSTEM
11305                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11306             r.persistent = true;
11307         }
11308         addProcessNameLocked(r);
11309         return r;
11310     }
11311
11312     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11313             String abiOverride) {
11314         ProcessRecord app;
11315         if (!isolated) {
11316             app = getProcessRecordLocked(info.processName, info.uid, true);
11317         } else {
11318             app = null;
11319         }
11320
11321         if (app == null) {
11322             app = newProcessRecordLocked(info, null, isolated, 0);
11323             updateLruProcessLocked(app, false, null);
11324             updateOomAdjLocked();
11325         }
11326
11327         // This package really, really can not be stopped.
11328         try {
11329             AppGlobals.getPackageManager().setPackageStoppedState(
11330                     info.packageName, false, UserHandle.getUserId(app.uid));
11331         } catch (RemoteException e) {
11332         } catch (IllegalArgumentException e) {
11333             Slog.w(TAG, "Failed trying to unstop package "
11334                     + info.packageName + ": " + e);
11335         }
11336
11337         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11338             app.persistent = true;
11339             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11340         }
11341         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11342             mPersistentStartingProcesses.add(app);
11343             startProcessLocked(app, "added application", app.processName, abiOverride,
11344                     null /* entryPoint */, null /* entryPointArgs */);
11345         }
11346
11347         return app;
11348     }
11349
11350     public void unhandledBack() {
11351         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11352                 "unhandledBack()");
11353
11354         synchronized(this) {
11355             final long origId = Binder.clearCallingIdentity();
11356             try {
11357                 getFocusedStack().unhandledBackLocked();
11358             } finally {
11359                 Binder.restoreCallingIdentity(origId);
11360             }
11361         }
11362     }
11363
11364     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11365         enforceNotIsolatedCaller("openContentUri");
11366         final int userId = UserHandle.getCallingUserId();
11367         String name = uri.getAuthority();
11368         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11369         ParcelFileDescriptor pfd = null;
11370         if (cph != null) {
11371             // We record the binder invoker's uid in thread-local storage before
11372             // going to the content provider to open the file.  Later, in the code
11373             // that handles all permissions checks, we look for this uid and use
11374             // that rather than the Activity Manager's own uid.  The effect is that
11375             // we do the check against the caller's permissions even though it looks
11376             // to the content provider like the Activity Manager itself is making
11377             // the request.
11378             Binder token = new Binder();
11379             sCallerIdentity.set(new Identity(
11380                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11381             try {
11382                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11383             } catch (FileNotFoundException e) {
11384                 // do nothing; pfd will be returned null
11385             } finally {
11386                 // Ensure that whatever happens, we clean up the identity state
11387                 sCallerIdentity.remove();
11388                 // Ensure we're done with the provider.
11389                 removeContentProviderExternalUnchecked(name, null, userId);
11390             }
11391         } else {
11392             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11393         }
11394         return pfd;
11395     }
11396
11397     // Actually is sleeping or shutting down or whatever else in the future
11398     // is an inactive state.
11399     public boolean isSleepingOrShuttingDown() {
11400         return isSleeping() || mShuttingDown;
11401     }
11402
11403     public boolean isSleeping() {
11404         return mSleeping;
11405     }
11406
11407     void onWakefulnessChanged(int wakefulness) {
11408         synchronized(this) {
11409             mWakefulness = wakefulness;
11410             updateSleepIfNeededLocked();
11411         }
11412     }
11413
11414     void finishRunningVoiceLocked() {
11415         if (mRunningVoice != null) {
11416             mRunningVoice = null;
11417             mVoiceWakeLock.release();
11418             updateSleepIfNeededLocked();
11419         }
11420     }
11421
11422     void startTimeTrackingFocusedActivityLocked() {
11423         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11424             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11425         }
11426     }
11427
11428     void updateSleepIfNeededLocked() {
11429         if (mSleeping && !shouldSleepLocked()) {
11430             mSleeping = false;
11431             startTimeTrackingFocusedActivityLocked();
11432             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11433             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11434             updateOomAdjLocked();
11435         } else if (!mSleeping && shouldSleepLocked()) {
11436             mSleeping = true;
11437             if (mCurAppTimeTracker != null) {
11438                 mCurAppTimeTracker.stop();
11439             }
11440             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11441             mStackSupervisor.goingToSleepLocked();
11442             updateOomAdjLocked();
11443
11444             // Initialize the wake times of all processes.
11445             checkExcessivePowerUsageLocked(false);
11446             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11447             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11448             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11449         }
11450     }
11451
11452     private boolean shouldSleepLocked() {
11453         // Resume applications while running a voice interactor.
11454         if (mRunningVoice != null) {
11455             return false;
11456         }
11457
11458         // TODO: Transform the lock screen state into a sleep token instead.
11459         switch (mWakefulness) {
11460             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11461             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11462             case PowerManagerInternal.WAKEFULNESS_DOZING:
11463                 // Pause applications whenever the lock screen is shown or any sleep
11464                 // tokens have been acquired.
11465                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11466             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11467             default:
11468                 // If we're asleep then pause applications unconditionally.
11469                 return true;
11470         }
11471     }
11472
11473     /** Pokes the task persister. */
11474     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11475         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11476     }
11477
11478     /** Notifies all listeners when the task stack has changed. */
11479     void notifyTaskStackChangedLocked() {
11480         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11481         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11482         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11483         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11484     }
11485
11486     /** Notifies all listeners when an Activity is pinned. */
11487     void notifyActivityPinnedLocked() {
11488         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11489         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11490     }
11491
11492     /**
11493      * Notifies all listeners when an attempt was made to start an an activity that is already
11494      * running in the pinned stack and the activity was not actually started, but the task is
11495      * either brought to the front or a new Intent is delivered to it.
11496      */
11497     void notifyPinnedActivityRestartAttemptLocked() {
11498         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11499         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11500     }
11501
11502     /** Notifies all listeners when the pinned stack animation ends. */
11503     @Override
11504     public void notifyPinnedStackAnimationEnded() {
11505         synchronized (this) {
11506             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11507             mHandler.obtainMessage(
11508                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11509         }
11510     }
11511
11512     @Override
11513     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11514         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11515     }
11516
11517     @Override
11518     public boolean shutdown(int timeout) {
11519         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11520                 != PackageManager.PERMISSION_GRANTED) {
11521             throw new SecurityException("Requires permission "
11522                     + android.Manifest.permission.SHUTDOWN);
11523         }
11524
11525         boolean timedout = false;
11526
11527         synchronized(this) {
11528             mShuttingDown = true;
11529             updateEventDispatchingLocked();
11530             timedout = mStackSupervisor.shutdownLocked(timeout);
11531         }
11532
11533         mAppOpsService.shutdown();
11534         if (mUsageStatsService != null) {
11535             mUsageStatsService.prepareShutdown();
11536         }
11537         mBatteryStatsService.shutdown();
11538         synchronized (this) {
11539             mProcessStats.shutdownLocked();
11540             notifyTaskPersisterLocked(null, true);
11541         }
11542
11543         return timedout;
11544     }
11545
11546     public final void activitySlept(IBinder token) {
11547         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11548
11549         final long origId = Binder.clearCallingIdentity();
11550
11551         synchronized (this) {
11552             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11553             if (r != null) {
11554                 mStackSupervisor.activitySleptLocked(r);
11555             }
11556         }
11557
11558         Binder.restoreCallingIdentity(origId);
11559     }
11560
11561     private String lockScreenShownToString() {
11562         switch (mLockScreenShown) {
11563             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11564             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11565             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11566             default: return "Unknown=" + mLockScreenShown;
11567         }
11568     }
11569
11570     void logLockScreen(String msg) {
11571         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11572                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11573                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11574                 + " mSleeping=" + mSleeping);
11575     }
11576
11577     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11578         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11579         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11580         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11581             boolean wasRunningVoice = mRunningVoice != null;
11582             mRunningVoice = session;
11583             if (!wasRunningVoice) {
11584                 mVoiceWakeLock.acquire();
11585                 updateSleepIfNeededLocked();
11586             }
11587         }
11588     }
11589
11590     private void updateEventDispatchingLocked() {
11591         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11592     }
11593
11594     public void setLockScreenShown(boolean showing, boolean occluded) {
11595         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11596                 != PackageManager.PERMISSION_GRANTED) {
11597             throw new SecurityException("Requires permission "
11598                     + android.Manifest.permission.DEVICE_POWER);
11599         }
11600
11601         synchronized(this) {
11602             long ident = Binder.clearCallingIdentity();
11603             try {
11604                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11605                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11606                 if (showing && occluded) {
11607                     // The lock screen is currently showing, but is occluded by a window that can
11608                     // show on top of the lock screen. In this can we want to dismiss the docked
11609                     // stack since it will be complicated/risky to try to put the activity on top
11610                     // of the lock screen in the right fullscreen configuration.
11611                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11612                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11613                 }
11614
11615                 updateSleepIfNeededLocked();
11616             } finally {
11617                 Binder.restoreCallingIdentity(ident);
11618             }
11619         }
11620     }
11621
11622     @Override
11623     public void notifyLockedProfile(@UserIdInt int userId) {
11624         try {
11625             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11626                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11627             }
11628         } catch (RemoteException ex) {
11629             throw new SecurityException("Fail to check is caller a privileged app", ex);
11630         }
11631
11632         synchronized (this) {
11633             if (mStackSupervisor.isUserLockedProfile(userId)) {
11634                 final long ident = Binder.clearCallingIdentity();
11635                 try {
11636                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11637                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11638                         // If there is no device lock, we will show the profile's credential page.
11639                         mActivityStarter.showConfirmDeviceCredential(userId);
11640                     } else {
11641                         // Showing launcher to avoid user entering credential twice.
11642                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11643                     }
11644                 } finally {
11645                     Binder.restoreCallingIdentity(ident);
11646                 }
11647             }
11648         }
11649     }
11650
11651     @Override
11652     public void startConfirmDeviceCredentialIntent(Intent intent) {
11653         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11654         synchronized (this) {
11655             final long ident = Binder.clearCallingIdentity();
11656             try {
11657                 mActivityStarter.startConfirmCredentialIntent(intent);
11658             } finally {
11659                 Binder.restoreCallingIdentity(ident);
11660             }
11661         }
11662     }
11663
11664     @Override
11665     public void stopAppSwitches() {
11666         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11667                 != PackageManager.PERMISSION_GRANTED) {
11668             throw new SecurityException("viewquires permission "
11669                     + android.Manifest.permission.STOP_APP_SWITCHES);
11670         }
11671
11672         synchronized(this) {
11673             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11674                     + APP_SWITCH_DELAY_TIME;
11675             mDidAppSwitch = false;
11676             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11677             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11678             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11679         }
11680     }
11681
11682     public void resumeAppSwitches() {
11683         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11684                 != PackageManager.PERMISSION_GRANTED) {
11685             throw new SecurityException("Requires permission "
11686                     + android.Manifest.permission.STOP_APP_SWITCHES);
11687         }
11688
11689         synchronized(this) {
11690             // Note that we don't execute any pending app switches... we will
11691             // let those wait until either the timeout, or the next start
11692             // activity request.
11693             mAppSwitchesAllowedTime = 0;
11694         }
11695     }
11696
11697     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11698             int callingPid, int callingUid, String name) {
11699         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11700             return true;
11701         }
11702
11703         int perm = checkComponentPermission(
11704                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11705                 sourceUid, -1, true);
11706         if (perm == PackageManager.PERMISSION_GRANTED) {
11707             return true;
11708         }
11709
11710         // If the actual IPC caller is different from the logical source, then
11711         // also see if they are allowed to control app switches.
11712         if (callingUid != -1 && callingUid != sourceUid) {
11713             perm = checkComponentPermission(
11714                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11715                     callingUid, -1, true);
11716             if (perm == PackageManager.PERMISSION_GRANTED) {
11717                 return true;
11718             }
11719         }
11720
11721         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11722         return false;
11723     }
11724
11725     public void setDebugApp(String packageName, boolean waitForDebugger,
11726             boolean persistent) {
11727         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11728                 "setDebugApp()");
11729
11730         long ident = Binder.clearCallingIdentity();
11731         try {
11732             // Note that this is not really thread safe if there are multiple
11733             // callers into it at the same time, but that's not a situation we
11734             // care about.
11735             if (persistent) {
11736                 final ContentResolver resolver = mContext.getContentResolver();
11737                 Settings.Global.putString(
11738                     resolver, Settings.Global.DEBUG_APP,
11739                     packageName);
11740                 Settings.Global.putInt(
11741                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11742                     waitForDebugger ? 1 : 0);
11743             }
11744
11745             synchronized (this) {
11746                 if (!persistent) {
11747                     mOrigDebugApp = mDebugApp;
11748                     mOrigWaitForDebugger = mWaitForDebugger;
11749                 }
11750                 mDebugApp = packageName;
11751                 mWaitForDebugger = waitForDebugger;
11752                 mDebugTransient = !persistent;
11753                 if (packageName != null) {
11754                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11755                             false, UserHandle.USER_ALL, "set debug app");
11756                 }
11757             }
11758         } finally {
11759             Binder.restoreCallingIdentity(ident);
11760         }
11761     }
11762
11763     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11764         synchronized (this) {
11765             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11766             if (!isDebuggable) {
11767                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11768                     throw new SecurityException("Process not debuggable: " + app.packageName);
11769                 }
11770             }
11771
11772             mTrackAllocationApp = processName;
11773         }
11774     }
11775
11776     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11777         synchronized (this) {
11778             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11779             if (!isDebuggable) {
11780                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11781                     throw new SecurityException("Process not debuggable: " + app.packageName);
11782                 }
11783             }
11784             mProfileApp = processName;
11785             mProfileFile = profilerInfo.profileFile;
11786             if (mProfileFd != null) {
11787                 try {
11788                     mProfileFd.close();
11789                 } catch (IOException e) {
11790                 }
11791                 mProfileFd = null;
11792             }
11793             mProfileFd = profilerInfo.profileFd;
11794             mSamplingInterval = profilerInfo.samplingInterval;
11795             mAutoStopProfiler = profilerInfo.autoStopProfiler;
11796             mProfileType = 0;
11797         }
11798     }
11799
11800     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11801         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11802         if (!isDebuggable) {
11803             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11804                 throw new SecurityException("Process not debuggable: " + app.packageName);
11805             }
11806         }
11807         mNativeDebuggingApp = processName;
11808     }
11809
11810     @Override
11811     public void setAlwaysFinish(boolean enabled) {
11812         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11813                 "setAlwaysFinish()");
11814
11815         long ident = Binder.clearCallingIdentity();
11816         try {
11817             Settings.Global.putInt(
11818                     mContext.getContentResolver(),
11819                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11820
11821             synchronized (this) {
11822                 mAlwaysFinishActivities = enabled;
11823             }
11824         } finally {
11825             Binder.restoreCallingIdentity(ident);
11826         }
11827     }
11828
11829     @Override
11830     public void setLenientBackgroundCheck(boolean enabled) {
11831         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11832                 "setLenientBackgroundCheck()");
11833
11834         long ident = Binder.clearCallingIdentity();
11835         try {
11836             Settings.Global.putInt(
11837                     mContext.getContentResolver(),
11838                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11839
11840             synchronized (this) {
11841                 mLenientBackgroundCheck = enabled;
11842             }
11843         } finally {
11844             Binder.restoreCallingIdentity(ident);
11845         }
11846     }
11847
11848     @Override
11849     public void setActivityController(IActivityController controller, boolean imAMonkey) {
11850         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11851                 "setActivityController()");
11852         synchronized (this) {
11853             mController = controller;
11854             mControllerIsAMonkey = imAMonkey;
11855             Watchdog.getInstance().setActivityController(controller);
11856         }
11857     }
11858
11859     @Override
11860     public void setUserIsMonkey(boolean userIsMonkey) {
11861         synchronized (this) {
11862             synchronized (mPidsSelfLocked) {
11863                 final int callingPid = Binder.getCallingPid();
11864                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11865                 if (precessRecord == null) {
11866                     throw new SecurityException("Unknown process: " + callingPid);
11867                 }
11868                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
11869                     throw new SecurityException("Only an instrumentation process "
11870                             + "with a UiAutomation can call setUserIsMonkey");
11871                 }
11872             }
11873             mUserIsMonkey = userIsMonkey;
11874         }
11875     }
11876
11877     @Override
11878     public boolean isUserAMonkey() {
11879         synchronized (this) {
11880             // If there is a controller also implies the user is a monkey.
11881             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11882         }
11883     }
11884
11885     public void requestBugReport(int bugreportType) {
11886         String service = null;
11887         switch (bugreportType) {
11888             case ActivityManager.BUGREPORT_OPTION_FULL:
11889                 service = "bugreport";
11890                 break;
11891             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11892                 service = "bugreportplus";
11893                 break;
11894             case ActivityManager.BUGREPORT_OPTION_REMOTE:
11895                 service = "bugreportremote";
11896                 break;
11897         }
11898         if (service == null) {
11899             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11900                     + bugreportType);
11901         }
11902         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11903         SystemProperties.set("ctl.start", service);
11904     }
11905
11906     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11907         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11908     }
11909
11910     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11911         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11912             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11913         }
11914         return KEY_DISPATCHING_TIMEOUT;
11915     }
11916
11917     @Override
11918     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11919         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11920                 != PackageManager.PERMISSION_GRANTED) {
11921             throw new SecurityException("Requires permission "
11922                     + android.Manifest.permission.FILTER_EVENTS);
11923         }
11924         ProcessRecord proc;
11925         long timeout;
11926         synchronized (this) {
11927             synchronized (mPidsSelfLocked) {
11928                 proc = mPidsSelfLocked.get(pid);
11929             }
11930             timeout = getInputDispatchingTimeoutLocked(proc);
11931         }
11932
11933         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11934             return -1;
11935         }
11936
11937         return timeout;
11938     }
11939
11940     /**
11941      * Handle input dispatching timeouts.
11942      * Returns whether input dispatching should be aborted or not.
11943      */
11944     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11945             final ActivityRecord activity, final ActivityRecord parent,
11946             final boolean aboveSystem, String reason) {
11947         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11948                 != PackageManager.PERMISSION_GRANTED) {
11949             throw new SecurityException("Requires permission "
11950                     + android.Manifest.permission.FILTER_EVENTS);
11951         }
11952
11953         final String annotation;
11954         if (reason == null) {
11955             annotation = "Input dispatching timed out";
11956         } else {
11957             annotation = "Input dispatching timed out (" + reason + ")";
11958         }
11959
11960         if (proc != null) {
11961             synchronized (this) {
11962                 if (proc.debugging) {
11963                     return false;
11964                 }
11965
11966                 if (mDidDexOpt) {
11967                     // Give more time since we were dexopting.
11968                     mDidDexOpt = false;
11969                     return false;
11970                 }
11971
11972                 if (proc.instrumentationClass != null) {
11973                     Bundle info = new Bundle();
11974                     info.putString("shortMsg", "keyDispatchingTimedOut");
11975                     info.putString("longMsg", annotation);
11976                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11977                     return true;
11978                 }
11979             }
11980             mHandler.post(new Runnable() {
11981                 @Override
11982                 public void run() {
11983                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11984                 }
11985             });
11986         }
11987
11988         return true;
11989     }
11990
11991     @Override
11992     public Bundle getAssistContextExtras(int requestType) {
11993         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11994                 null, null, true /* focused */, true /* newSessionId */,
11995                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11996         if (pae == null) {
11997             return null;
11998         }
11999         synchronized (pae) {
12000             while (!pae.haveResult) {
12001                 try {
12002                     pae.wait();
12003                 } catch (InterruptedException e) {
12004                 }
12005             }
12006         }
12007         synchronized (this) {
12008             buildAssistBundleLocked(pae, pae.result);
12009             mPendingAssistExtras.remove(pae);
12010             mUiHandler.removeCallbacks(pae);
12011         }
12012         return pae.extras;
12013     }
12014
12015     @Override
12016     public boolean isAssistDataAllowedOnCurrentActivity() {
12017         int userId;
12018         synchronized (this) {
12019             userId = mUserController.getCurrentUserIdLocked();
12020             ActivityRecord activity = getFocusedStack().topActivity();
12021             if (activity == null) {
12022                 return false;
12023             }
12024             userId = activity.userId;
12025         }
12026         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12027                 Context.DEVICE_POLICY_SERVICE);
12028         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12029     }
12030
12031     @Override
12032     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12033         long ident = Binder.clearCallingIdentity();
12034         try {
12035             synchronized (this) {
12036                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12037                 ActivityRecord top = getFocusedStack().topActivity();
12038                 if (top != caller) {
12039                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12040                             + " is not current top " + top);
12041                     return false;
12042                 }
12043                 if (!top.nowVisible) {
12044                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12045                             + " is not visible");
12046                     return false;
12047                 }
12048             }
12049             AssistUtils utils = new AssistUtils(mContext);
12050             return utils.showSessionForActiveService(args,
12051                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12052         } finally {
12053             Binder.restoreCallingIdentity(ident);
12054         }
12055     }
12056
12057     @Override
12058     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12059             Bundle receiverExtras,
12060             IBinder activityToken, boolean focused, boolean newSessionId) {
12061         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12062                 activityToken, focused, newSessionId,
12063                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12064                 != null;
12065     }
12066
12067     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12068             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12069             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12070         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12071                 "enqueueAssistContext()");
12072         synchronized (this) {
12073             ActivityRecord activity = getFocusedStack().topActivity();
12074             if (activity == null) {
12075                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12076                 return null;
12077             }
12078             if (activity.app == null || activity.app.thread == null) {
12079                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12080                 return null;
12081             }
12082             if (focused) {
12083                 if (activityToken != null) {
12084                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12085                     if (activity != caller) {
12086                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12087                                 + " is not current top " + activity);
12088                         return null;
12089                     }
12090                 }
12091             } else {
12092                 activity = ActivityRecord.forTokenLocked(activityToken);
12093                 if (activity == null) {
12094                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12095                             + " couldn't be found");
12096                     return null;
12097                 }
12098             }
12099
12100             PendingAssistExtras pae;
12101             Bundle extras = new Bundle();
12102             if (args != null) {
12103                 extras.putAll(args);
12104             }
12105             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12106             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12107             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12108                     userHandle);
12109             // Increment the sessionId if necessary
12110             if (newSessionId) {
12111                 mViSessionId++;
12112             }
12113             try {
12114                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12115                         requestType, mViSessionId);
12116                 mPendingAssistExtras.add(pae);
12117                 mUiHandler.postDelayed(pae, timeout);
12118             } catch (RemoteException e) {
12119                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12120                 return null;
12121             }
12122             return pae;
12123         }
12124     }
12125
12126     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12127         IResultReceiver receiver;
12128         synchronized (this) {
12129             mPendingAssistExtras.remove(pae);
12130             receiver = pae.receiver;
12131         }
12132         if (receiver != null) {
12133             // Caller wants result sent back to them.
12134             Bundle sendBundle = new Bundle();
12135             // At least return the receiver extras
12136             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12137                     pae.receiverExtras);
12138             try {
12139                 pae.receiver.send(0, sendBundle);
12140             } catch (RemoteException e) {
12141             }
12142         }
12143     }
12144
12145     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12146         if (result != null) {
12147             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12148         }
12149         if (pae.hint != null) {
12150             pae.extras.putBoolean(pae.hint, true);
12151         }
12152     }
12153
12154     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12155             AssistContent content, Uri referrer) {
12156         PendingAssistExtras pae = (PendingAssistExtras)token;
12157         synchronized (pae) {
12158             pae.result = extras;
12159             pae.structure = structure;
12160             pae.content = content;
12161             if (referrer != null) {
12162                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12163             }
12164             pae.haveResult = true;
12165             pae.notifyAll();
12166             if (pae.intent == null && pae.receiver == null) {
12167                 // Caller is just waiting for the result.
12168                 return;
12169             }
12170         }
12171
12172         // We are now ready to launch the assist activity.
12173         IResultReceiver sendReceiver = null;
12174         Bundle sendBundle = null;
12175         synchronized (this) {
12176             buildAssistBundleLocked(pae, extras);
12177             boolean exists = mPendingAssistExtras.remove(pae);
12178             mUiHandler.removeCallbacks(pae);
12179             if (!exists) {
12180                 // Timed out.
12181                 return;
12182             }
12183             if ((sendReceiver=pae.receiver) != null) {
12184                 // Caller wants result sent back to them.
12185                 sendBundle = new Bundle();
12186                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12187                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12188                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12189                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12190                         pae.receiverExtras);
12191             }
12192         }
12193         if (sendReceiver != null) {
12194             try {
12195                 sendReceiver.send(0, sendBundle);
12196             } catch (RemoteException e) {
12197             }
12198             return;
12199         }
12200
12201         long ident = Binder.clearCallingIdentity();
12202         try {
12203             pae.intent.replaceExtras(pae.extras);
12204             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12205                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12206                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12207             closeSystemDialogs("assist");
12208             try {
12209                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12210             } catch (ActivityNotFoundException e) {
12211                 Slog.w(TAG, "No activity to handle assist action.", e);
12212             }
12213         } finally {
12214             Binder.restoreCallingIdentity(ident);
12215         }
12216     }
12217
12218     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12219             Bundle args) {
12220         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12221                 true /* focused */, true /* newSessionId */,
12222                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12223     }
12224
12225     public void registerProcessObserver(IProcessObserver observer) {
12226         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12227                 "registerProcessObserver()");
12228         synchronized (this) {
12229             mProcessObservers.register(observer);
12230         }
12231     }
12232
12233     @Override
12234     public void unregisterProcessObserver(IProcessObserver observer) {
12235         synchronized (this) {
12236             mProcessObservers.unregister(observer);
12237         }
12238     }
12239
12240     @Override
12241     public void registerUidObserver(IUidObserver observer, int which) {
12242         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12243                 "registerUidObserver()");
12244         synchronized (this) {
12245             mUidObservers.register(observer, which);
12246         }
12247     }
12248
12249     @Override
12250     public void unregisterUidObserver(IUidObserver observer) {
12251         synchronized (this) {
12252             mUidObservers.unregister(observer);
12253         }
12254     }
12255
12256     @Override
12257     public boolean convertFromTranslucent(IBinder token) {
12258         final long origId = Binder.clearCallingIdentity();
12259         try {
12260             synchronized (this) {
12261                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12262                 if (r == null) {
12263                     return false;
12264                 }
12265                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12266                 if (translucentChanged) {
12267                     r.task.stack.releaseBackgroundResources(r);
12268                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12269                 }
12270                 mWindowManager.setAppFullscreen(token, true);
12271                 return translucentChanged;
12272             }
12273         } finally {
12274             Binder.restoreCallingIdentity(origId);
12275         }
12276     }
12277
12278     @Override
12279     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12280         final long origId = Binder.clearCallingIdentity();
12281         try {
12282             synchronized (this) {
12283                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12284                 if (r == null) {
12285                     return false;
12286                 }
12287                 int index = r.task.mActivities.lastIndexOf(r);
12288                 if (index > 0) {
12289                     ActivityRecord under = r.task.mActivities.get(index - 1);
12290                     under.returningOptions = options;
12291                 }
12292                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12293                 if (translucentChanged) {
12294                     r.task.stack.convertActivityToTranslucent(r);
12295                 }
12296                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12297                 mWindowManager.setAppFullscreen(token, false);
12298                 return translucentChanged;
12299             }
12300         } finally {
12301             Binder.restoreCallingIdentity(origId);
12302         }
12303     }
12304
12305     @Override
12306     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12307         final long origId = Binder.clearCallingIdentity();
12308         try {
12309             synchronized (this) {
12310                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12311                 if (r != null) {
12312                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12313                 }
12314             }
12315             return false;
12316         } finally {
12317             Binder.restoreCallingIdentity(origId);
12318         }
12319     }
12320
12321     @Override
12322     public boolean isBackgroundVisibleBehind(IBinder token) {
12323         final long origId = Binder.clearCallingIdentity();
12324         try {
12325             synchronized (this) {
12326                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12327                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12328                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12329                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12330                 return visible;
12331             }
12332         } finally {
12333             Binder.restoreCallingIdentity(origId);
12334         }
12335     }
12336
12337     @Override
12338     public ActivityOptions getActivityOptions(IBinder token) {
12339         final long origId = Binder.clearCallingIdentity();
12340         try {
12341             synchronized (this) {
12342                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12343                 if (r != null) {
12344                     final ActivityOptions activityOptions = r.pendingOptions;
12345                     r.pendingOptions = null;
12346                     return activityOptions;
12347                 }
12348                 return null;
12349             }
12350         } finally {
12351             Binder.restoreCallingIdentity(origId);
12352         }
12353     }
12354
12355     @Override
12356     public void setImmersive(IBinder token, boolean immersive) {
12357         synchronized(this) {
12358             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12359             if (r == null) {
12360                 throw new IllegalArgumentException();
12361             }
12362             r.immersive = immersive;
12363
12364             // update associated state if we're frontmost
12365             if (r == mFocusedActivity) {
12366                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12367                 applyUpdateLockStateLocked(r);
12368             }
12369         }
12370     }
12371
12372     @Override
12373     public boolean isImmersive(IBinder token) {
12374         synchronized (this) {
12375             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12376             if (r == null) {
12377                 throw new IllegalArgumentException();
12378             }
12379             return r.immersive;
12380         }
12381     }
12382
12383     @Override
12384     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12385         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12386             throw new UnsupportedOperationException("VR mode not supported on this device!");
12387         }
12388
12389         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12390
12391         ActivityRecord r;
12392         synchronized (this) {
12393             r = ActivityRecord.isInStackLocked(token);
12394         }
12395
12396         if (r == null) {
12397             throw new IllegalArgumentException();
12398         }
12399
12400         int err;
12401         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12402                 VrManagerInternal.NO_ERROR) {
12403             return err;
12404         }
12405
12406         synchronized(this) {
12407             r.requestedVrComponent = (enabled) ? packageName : null;
12408
12409             // Update associated state if this activity is currently focused
12410             if (r == mFocusedActivity) {
12411                 applyUpdateVrModeLocked(r);
12412             }
12413             return 0;
12414         }
12415     }
12416
12417     @Override
12418     public boolean isVrModePackageEnabled(ComponentName packageName) {
12419         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12420             throw new UnsupportedOperationException("VR mode not supported on this device!");
12421         }
12422
12423         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12424
12425         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12426                 VrManagerInternal.NO_ERROR;
12427     }
12428
12429     public boolean isTopActivityImmersive() {
12430         enforceNotIsolatedCaller("startActivity");
12431         synchronized (this) {
12432             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12433             return (r != null) ? r.immersive : false;
12434         }
12435     }
12436
12437     @Override
12438     public boolean isTopOfTask(IBinder token) {
12439         synchronized (this) {
12440             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12441             if (r == null) {
12442                 throw new IllegalArgumentException();
12443             }
12444             return r.task.getTopActivity() == r;
12445         }
12446     }
12447
12448     public final void enterSafeMode() {
12449         synchronized(this) {
12450             // It only makes sense to do this before the system is ready
12451             // and started launching other packages.
12452             if (!mSystemReady) {
12453                 try {
12454                     AppGlobals.getPackageManager().enterSafeMode();
12455                 } catch (RemoteException e) {
12456                 }
12457             }
12458
12459             mSafeMode = true;
12460         }
12461     }
12462
12463     public final void showSafeModeOverlay() {
12464         View v = LayoutInflater.from(mContext).inflate(
12465                 com.android.internal.R.layout.safe_mode, null);
12466         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12467         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12468         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12469         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12470         lp.gravity = Gravity.BOTTOM | Gravity.START;
12471         lp.format = v.getBackground().getOpacity();
12472         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12473                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12474         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12475         ((WindowManager)mContext.getSystemService(
12476                 Context.WINDOW_SERVICE)).addView(v, lp);
12477     }
12478
12479     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12480         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12481             return;
12482         }
12483         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12484         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12485         synchronized (stats) {
12486             if (mBatteryStatsService.isOnBattery()) {
12487                 mBatteryStatsService.enforceCallingPermission();
12488                 int MY_UID = Binder.getCallingUid();
12489                 final int uid;
12490                 if (sender == null) {
12491                     uid = sourceUid;
12492                 } else {
12493                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12494                 }
12495                 BatteryStatsImpl.Uid.Pkg pkg =
12496                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12497                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12498                 pkg.noteWakeupAlarmLocked(tag);
12499             }
12500         }
12501     }
12502
12503     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12504         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12505             return;
12506         }
12507         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12508         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12509         synchronized (stats) {
12510             mBatteryStatsService.enforceCallingPermission();
12511             int MY_UID = Binder.getCallingUid();
12512             final int uid;
12513             if (sender == null) {
12514                 uid = sourceUid;
12515             } else {
12516                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12517             }
12518             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12519         }
12520     }
12521
12522     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12523         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12524             return;
12525         }
12526         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12527         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12528         synchronized (stats) {
12529             mBatteryStatsService.enforceCallingPermission();
12530             int MY_UID = Binder.getCallingUid();
12531             final int uid;
12532             if (sender == null) {
12533                 uid = sourceUid;
12534             } else {
12535                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12536             }
12537             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12538         }
12539     }
12540
12541     public boolean killPids(int[] pids, String pReason, boolean secure) {
12542         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12543             throw new SecurityException("killPids only available to the system");
12544         }
12545         String reason = (pReason == null) ? "Unknown" : pReason;
12546         // XXX Note: don't acquire main activity lock here, because the window
12547         // manager calls in with its locks held.
12548
12549         boolean killed = false;
12550         synchronized (mPidsSelfLocked) {
12551             int worstType = 0;
12552             for (int i=0; i<pids.length; i++) {
12553                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12554                 if (proc != null) {
12555                     int type = proc.setAdj;
12556                     if (type > worstType) {
12557                         worstType = type;
12558                     }
12559                 }
12560             }
12561
12562             // If the worst oom_adj is somewhere in the cached proc LRU range,
12563             // then constrain it so we will kill all cached procs.
12564             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12565                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12566                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12567             }
12568
12569             // If this is not a secure call, don't let it kill processes that
12570             // are important.
12571             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12572                 worstType = ProcessList.SERVICE_ADJ;
12573             }
12574
12575             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12576             for (int i=0; i<pids.length; i++) {
12577                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12578                 if (proc == null) {
12579                     continue;
12580                 }
12581                 int adj = proc.setAdj;
12582                 if (adj >= worstType && !proc.killedByAm) {
12583                     proc.kill(reason, true);
12584                     killed = true;
12585                 }
12586             }
12587         }
12588         return killed;
12589     }
12590
12591     @Override
12592     public void killUid(int appId, int userId, String reason) {
12593         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12594         synchronized (this) {
12595             final long identity = Binder.clearCallingIdentity();
12596             try {
12597                 killPackageProcessesLocked(null, appId, userId,
12598                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12599                         reason != null ? reason : "kill uid");
12600             } finally {
12601                 Binder.restoreCallingIdentity(identity);
12602             }
12603         }
12604     }
12605
12606     @Override
12607     public boolean killProcessesBelowForeground(String reason) {
12608         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12609             throw new SecurityException("killProcessesBelowForeground() only available to system");
12610         }
12611
12612         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12613     }
12614
12615     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12616         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12617             throw new SecurityException("killProcessesBelowAdj() only available to system");
12618         }
12619
12620         boolean killed = false;
12621         synchronized (mPidsSelfLocked) {
12622             final int size = mPidsSelfLocked.size();
12623             for (int i = 0; i < size; i++) {
12624                 final int pid = mPidsSelfLocked.keyAt(i);
12625                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12626                 if (proc == null) continue;
12627
12628                 final int adj = proc.setAdj;
12629                 if (adj > belowAdj && !proc.killedByAm) {
12630                     proc.kill(reason, true);
12631                     killed = true;
12632                 }
12633             }
12634         }
12635         return killed;
12636     }
12637
12638     @Override
12639     public void hang(final IBinder who, boolean allowRestart) {
12640         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12641                 != PackageManager.PERMISSION_GRANTED) {
12642             throw new SecurityException("Requires permission "
12643                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12644         }
12645
12646         final IBinder.DeathRecipient death = new DeathRecipient() {
12647             @Override
12648             public void binderDied() {
12649                 synchronized (this) {
12650                     notifyAll();
12651                 }
12652             }
12653         };
12654
12655         try {
12656             who.linkToDeath(death, 0);
12657         } catch (RemoteException e) {
12658             Slog.w(TAG, "hang: given caller IBinder is already dead.");
12659             return;
12660         }
12661
12662         synchronized (this) {
12663             Watchdog.getInstance().setAllowRestart(allowRestart);
12664             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12665             synchronized (death) {
12666                 while (who.isBinderAlive()) {
12667                     try {
12668                         death.wait();
12669                     } catch (InterruptedException e) {
12670                     }
12671                 }
12672             }
12673             Watchdog.getInstance().setAllowRestart(true);
12674         }
12675     }
12676
12677     @Override
12678     public void restart() {
12679         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12680                 != PackageManager.PERMISSION_GRANTED) {
12681             throw new SecurityException("Requires permission "
12682                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12683         }
12684
12685         Log.i(TAG, "Sending shutdown broadcast...");
12686
12687         BroadcastReceiver br = new BroadcastReceiver() {
12688             @Override public void onReceive(Context context, Intent intent) {
12689                 // Now the broadcast is done, finish up the low-level shutdown.
12690                 Log.i(TAG, "Shutting down activity manager...");
12691                 shutdown(10000);
12692                 Log.i(TAG, "Shutdown complete, restarting!");
12693                 Process.killProcess(Process.myPid());
12694                 System.exit(10);
12695             }
12696         };
12697
12698         // First send the high-level shut down broadcast.
12699         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12700         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12701         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12702         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12703         mContext.sendOrderedBroadcastAsUser(intent,
12704                 UserHandle.ALL, null, br, mHandler, 0, null, null);
12705         */
12706         br.onReceive(mContext, intent);
12707     }
12708
12709     private long getLowRamTimeSinceIdle(long now) {
12710         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12711     }
12712
12713     @Override
12714     public void performIdleMaintenance() {
12715         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12716                 != PackageManager.PERMISSION_GRANTED) {
12717             throw new SecurityException("Requires permission "
12718                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12719         }
12720
12721         synchronized (this) {
12722             final long now = SystemClock.uptimeMillis();
12723             final long timeSinceLastIdle = now - mLastIdleTime;
12724             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12725             mLastIdleTime = now;
12726             mLowRamTimeSinceLastIdle = 0;
12727             if (mLowRamStartTime != 0) {
12728                 mLowRamStartTime = now;
12729             }
12730
12731             StringBuilder sb = new StringBuilder(128);
12732             sb.append("Idle maintenance over ");
12733             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12734             sb.append(" low RAM for ");
12735             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12736             Slog.i(TAG, sb.toString());
12737
12738             // If at least 1/3 of our time since the last idle period has been spent
12739             // with RAM low, then we want to kill processes.
12740             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12741
12742             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12743                 ProcessRecord proc = mLruProcesses.get(i);
12744                 if (proc.notCachedSinceIdle) {
12745                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12746                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12747                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12748                         if (doKilling && proc.initialIdlePss != 0
12749                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12750                             sb = new StringBuilder(128);
12751                             sb.append("Kill");
12752                             sb.append(proc.processName);
12753                             sb.append(" in idle maint: pss=");
12754                             sb.append(proc.lastPss);
12755                             sb.append(", swapPss=");
12756                             sb.append(proc.lastSwapPss);
12757                             sb.append(", initialPss=");
12758                             sb.append(proc.initialIdlePss);
12759                             sb.append(", period=");
12760                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12761                             sb.append(", lowRamPeriod=");
12762                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12763                             Slog.wtfQuiet(TAG, sb.toString());
12764                             proc.kill("idle maint (pss " + proc.lastPss
12765                                     + " from " + proc.initialIdlePss + ")", true);
12766                         }
12767                     }
12768                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12769                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12770                     proc.notCachedSinceIdle = true;
12771                     proc.initialIdlePss = 0;
12772                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12773                             mTestPssMode, isSleeping(), now);
12774                 }
12775             }
12776
12777             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12778             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12779         }
12780     }
12781
12782     @Override
12783     public void sendIdleJobTrigger() {
12784         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12785                 != PackageManager.PERMISSION_GRANTED) {
12786             throw new SecurityException("Requires permission "
12787                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12788         }
12789
12790         final long ident = Binder.clearCallingIdentity();
12791         try {
12792             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12793                     .setPackage("android")
12794                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12795             broadcastIntent(null, intent, null, null, 0, null, null, null,
12796                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12797         } finally {
12798             Binder.restoreCallingIdentity(ident);
12799         }
12800     }
12801
12802     private void retrieveSettings() {
12803         final ContentResolver resolver = mContext.getContentResolver();
12804         final boolean freeformWindowManagement =
12805                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12806                         || Settings.Global.getInt(
12807                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12808         final boolean supportsPictureInPicture =
12809                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12810
12811         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12812         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12813         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12814         final boolean alwaysFinishActivities =
12815                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12816         final boolean lenientBackgroundCheck =
12817                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12818         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12819         final boolean forceResizable = Settings.Global.getInt(
12820                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12821         // Transfer any global setting for forcing RTL layout, into a System Property
12822         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12823
12824         final Configuration configuration = new Configuration();
12825         Settings.System.getConfiguration(resolver, configuration);
12826         if (forceRtl) {
12827             // This will take care of setting the correct layout direction flags
12828             configuration.setLayoutDirection(configuration.locale);
12829         }
12830
12831         synchronized (this) {
12832             mDebugApp = mOrigDebugApp = debugApp;
12833             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12834             mAlwaysFinishActivities = alwaysFinishActivities;
12835             mLenientBackgroundCheck = lenientBackgroundCheck;
12836             mForceResizableActivities = forceResizable;
12837             mWindowManager.setForceResizableTasks(mForceResizableActivities);
12838             if (supportsMultiWindow || forceResizable) {
12839                 mSupportsMultiWindow = true;
12840                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12841                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12842             } else {
12843                 mSupportsMultiWindow = false;
12844                 mSupportsFreeformWindowManagement = false;
12845                 mSupportsPictureInPicture = false;
12846             }
12847             // This happens before any activities are started, so we can
12848             // change mConfiguration in-place.
12849             updateConfigurationLocked(configuration, null, true);
12850             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12851                     "Initial config: " + mConfiguration);
12852
12853             // Load resources only after the current configuration has been set.
12854             final Resources res = mContext.getResources();
12855             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12856             mThumbnailWidth = res.getDimensionPixelSize(
12857                     com.android.internal.R.dimen.thumbnail_width);
12858             mThumbnailHeight = res.getDimensionPixelSize(
12859                     com.android.internal.R.dimen.thumbnail_height);
12860             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12861                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
12862             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12863                     com.android.internal.R.string.config_appsNotReportingCrashes));
12864             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12865                 mFullscreenThumbnailScale = (float) res
12866                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12867                     (float) mConfiguration.screenWidthDp;
12868             } else {
12869                 mFullscreenThumbnailScale = res.getFraction(
12870                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12871             }
12872         }
12873     }
12874
12875     public boolean testIsSystemReady() {
12876         // no need to synchronize(this) just to read & return the value
12877         return mSystemReady;
12878     }
12879
12880     public void systemReady(final Runnable goingCallback) {
12881         synchronized(this) {
12882             if (mSystemReady) {
12883                 // If we're done calling all the receivers, run the next "boot phase" passed in
12884                 // by the SystemServer
12885                 if (goingCallback != null) {
12886                     goingCallback.run();
12887                 }
12888                 return;
12889             }
12890
12891             mLocalDeviceIdleController
12892                     = LocalServices.getService(DeviceIdleController.LocalService.class);
12893
12894             // Make sure we have the current profile info, since it is needed for security checks.
12895             mUserController.onSystemReady();
12896             mRecentTasks.onSystemReadyLocked();
12897             mAppOpsService.systemReady();
12898             mSystemReady = true;
12899         }
12900
12901         ArrayList<ProcessRecord> procsToKill = null;
12902         synchronized(mPidsSelfLocked) {
12903             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12904                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12905                 if (!isAllowedWhileBooting(proc.info)){
12906                     if (procsToKill == null) {
12907                         procsToKill = new ArrayList<ProcessRecord>();
12908                     }
12909                     procsToKill.add(proc);
12910                 }
12911             }
12912         }
12913
12914         synchronized(this) {
12915             if (procsToKill != null) {
12916                 for (int i=procsToKill.size()-1; i>=0; i--) {
12917                     ProcessRecord proc = procsToKill.get(i);
12918                     Slog.i(TAG, "Removing system update proc: " + proc);
12919                     removeProcessLocked(proc, true, false, "system update done");
12920                 }
12921             }
12922
12923             // Now that we have cleaned up any update processes, we
12924             // are ready to start launching real processes and know that
12925             // we won't trample on them any more.
12926             mProcessesReady = true;
12927         }
12928
12929         Slog.i(TAG, "System now ready");
12930         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12931             SystemClock.uptimeMillis());
12932
12933         synchronized(this) {
12934             // Make sure we have no pre-ready processes sitting around.
12935
12936             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12937                 ResolveInfo ri = mContext.getPackageManager()
12938                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12939                                 STOCK_PM_FLAGS);
12940                 CharSequence errorMsg = null;
12941                 if (ri != null) {
12942                     ActivityInfo ai = ri.activityInfo;
12943                     ApplicationInfo app = ai.applicationInfo;
12944                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12945                         mTopAction = Intent.ACTION_FACTORY_TEST;
12946                         mTopData = null;
12947                         mTopComponent = new ComponentName(app.packageName,
12948                                 ai.name);
12949                     } else {
12950                         errorMsg = mContext.getResources().getText(
12951                                 com.android.internal.R.string.factorytest_not_system);
12952                     }
12953                 } else {
12954                     errorMsg = mContext.getResources().getText(
12955                             com.android.internal.R.string.factorytest_no_action);
12956                 }
12957                 if (errorMsg != null) {
12958                     mTopAction = null;
12959                     mTopData = null;
12960                     mTopComponent = null;
12961                     Message msg = Message.obtain();
12962                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12963                     msg.getData().putCharSequence("msg", errorMsg);
12964                     mUiHandler.sendMessage(msg);
12965                 }
12966             }
12967         }
12968
12969         retrieveSettings();
12970         final int currentUserId;
12971         synchronized (this) {
12972             currentUserId = mUserController.getCurrentUserIdLocked();
12973             readGrantedUriPermissionsLocked();
12974         }
12975
12976         if (goingCallback != null) goingCallback.run();
12977
12978         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12979                 Integer.toString(currentUserId), currentUserId);
12980         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12981                 Integer.toString(currentUserId), currentUserId);
12982         mSystemServiceManager.startUser(currentUserId);
12983
12984         synchronized (this) {
12985             // Only start up encryption-aware persistent apps; once user is
12986             // unlocked we'll come back around and start unaware apps
12987             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12988
12989             // Start up initial activity.
12990             mBooting = true;
12991             // Enable home activity for system user, so that the system can always boot
12992             if (UserManager.isSplitSystemUser()) {
12993                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12994                 try {
12995                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12996                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12997                             UserHandle.USER_SYSTEM);
12998                 } catch (RemoteException e) {
12999                     throw e.rethrowAsRuntimeException();
13000                 }
13001             }
13002             startHomeActivityLocked(currentUserId, "systemReady");
13003
13004             try {
13005                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13006                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13007                             + " data partition or your device will be unstable.");
13008                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13009                 }
13010             } catch (RemoteException e) {
13011             }
13012
13013             if (!Build.isBuildConsistent()) {
13014                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13015                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13016             }
13017
13018             long ident = Binder.clearCallingIdentity();
13019             try {
13020                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13021                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13022                         | Intent.FLAG_RECEIVER_FOREGROUND);
13023                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13024                 broadcastIntentLocked(null, null, intent,
13025                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13026                         null, false, false, MY_PID, Process.SYSTEM_UID,
13027                         currentUserId);
13028                 intent = new Intent(Intent.ACTION_USER_STARTING);
13029                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13030                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13031                 broadcastIntentLocked(null, null, intent,
13032                         null, new IIntentReceiver.Stub() {
13033                             @Override
13034                             public void performReceive(Intent intent, int resultCode, String data,
13035                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13036                                     throws RemoteException {
13037                             }
13038                         }, 0, null, null,
13039                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13040                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13041             } catch (Throwable t) {
13042                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13043             } finally {
13044                 Binder.restoreCallingIdentity(ident);
13045             }
13046             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13047             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13048         }
13049     }
13050
13051     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13052         synchronized (this) {
13053             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13054         }
13055     }
13056
13057     void skipCurrentReceiverLocked(ProcessRecord app) {
13058         for (BroadcastQueue queue : mBroadcastQueues) {
13059             queue.skipCurrentReceiverLocked(app);
13060         }
13061     }
13062
13063     /**
13064      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13065      * The application process will exit immediately after this call returns.
13066      * @param app object of the crashing app, null for the system server
13067      * @param crashInfo describing the exception
13068      */
13069     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13070         ProcessRecord r = findAppProcess(app, "Crash");
13071         final String processName = app == null ? "system_server"
13072                 : (r == null ? "unknown" : r.processName);
13073
13074         handleApplicationCrashInner("crash", r, processName, crashInfo);
13075     }
13076
13077     /* Native crash reporting uses this inner version because it needs to be somewhat
13078      * decoupled from the AM-managed cleanup lifecycle
13079      */
13080     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13081             ApplicationErrorReport.CrashInfo crashInfo) {
13082         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13083                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13084                 r == null ? -1 : r.info.flags,
13085                 crashInfo.exceptionClassName,
13086                 crashInfo.exceptionMessage,
13087                 crashInfo.throwFileName,
13088                 crashInfo.throwLineNumber);
13089
13090         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13091
13092         mAppErrors.crashApplication(r, crashInfo);
13093     }
13094
13095     public void handleApplicationStrictModeViolation(
13096             IBinder app,
13097             int violationMask,
13098             StrictMode.ViolationInfo info) {
13099         ProcessRecord r = findAppProcess(app, "StrictMode");
13100         if (r == null) {
13101             return;
13102         }
13103
13104         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13105             Integer stackFingerprint = info.hashCode();
13106             boolean logIt = true;
13107             synchronized (mAlreadyLoggedViolatedStacks) {
13108                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13109                     logIt = false;
13110                     // TODO: sub-sample into EventLog for these, with
13111                     // the info.durationMillis?  Then we'd get
13112                     // the relative pain numbers, without logging all
13113                     // the stack traces repeatedly.  We'd want to do
13114                     // likewise in the client code, which also does
13115                     // dup suppression, before the Binder call.
13116                 } else {
13117                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13118                         mAlreadyLoggedViolatedStacks.clear();
13119                     }
13120                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13121                 }
13122             }
13123             if (logIt) {
13124                 logStrictModeViolationToDropBox(r, info);
13125             }
13126         }
13127
13128         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13129             AppErrorResult result = new AppErrorResult();
13130             synchronized (this) {
13131                 final long origId = Binder.clearCallingIdentity();
13132
13133                 Message msg = Message.obtain();
13134                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13135                 HashMap<String, Object> data = new HashMap<String, Object>();
13136                 data.put("result", result);
13137                 data.put("app", r);
13138                 data.put("violationMask", violationMask);
13139                 data.put("info", info);
13140                 msg.obj = data;
13141                 mUiHandler.sendMessage(msg);
13142
13143                 Binder.restoreCallingIdentity(origId);
13144             }
13145             int res = result.get();
13146             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13147         }
13148     }
13149
13150     // Depending on the policy in effect, there could be a bunch of
13151     // these in quick succession so we try to batch these together to
13152     // minimize disk writes, number of dropbox entries, and maximize
13153     // compression, by having more fewer, larger records.
13154     private void logStrictModeViolationToDropBox(
13155             ProcessRecord process,
13156             StrictMode.ViolationInfo info) {
13157         if (info == null) {
13158             return;
13159         }
13160         final boolean isSystemApp = process == null ||
13161                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13162                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13163         final String processName = process == null ? "unknown" : process.processName;
13164         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13165         final DropBoxManager dbox = (DropBoxManager)
13166                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13167
13168         // Exit early if the dropbox isn't configured to accept this report type.
13169         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13170
13171         boolean bufferWasEmpty;
13172         boolean needsFlush;
13173         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13174         synchronized (sb) {
13175             bufferWasEmpty = sb.length() == 0;
13176             appendDropBoxProcessHeaders(process, processName, sb);
13177             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13178             sb.append("System-App: ").append(isSystemApp).append("\n");
13179             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13180             if (info.violationNumThisLoop != 0) {
13181                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13182             }
13183             if (info.numAnimationsRunning != 0) {
13184                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13185             }
13186             if (info.broadcastIntentAction != null) {
13187                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13188             }
13189             if (info.durationMillis != -1) {
13190                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13191             }
13192             if (info.numInstances != -1) {
13193                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13194             }
13195             if (info.tags != null) {
13196                 for (String tag : info.tags) {
13197                     sb.append("Span-Tag: ").append(tag).append("\n");
13198                 }
13199             }
13200             sb.append("\n");
13201             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13202                 sb.append(info.crashInfo.stackTrace);
13203                 sb.append("\n");
13204             }
13205             if (info.message != null) {
13206                 sb.append(info.message);
13207                 sb.append("\n");
13208             }
13209
13210             // Only buffer up to ~64k.  Various logging bits truncate
13211             // things at 128k.
13212             needsFlush = (sb.length() > 64 * 1024);
13213         }
13214
13215         // Flush immediately if the buffer's grown too large, or this
13216         // is a non-system app.  Non-system apps are isolated with a
13217         // different tag & policy and not batched.
13218         //
13219         // Batching is useful during internal testing with
13220         // StrictMode settings turned up high.  Without batching,
13221         // thousands of separate files could be created on boot.
13222         if (!isSystemApp || needsFlush) {
13223             new Thread("Error dump: " + dropboxTag) {
13224                 @Override
13225                 public void run() {
13226                     String report;
13227                     synchronized (sb) {
13228                         report = sb.toString();
13229                         sb.delete(0, sb.length());
13230                         sb.trimToSize();
13231                     }
13232                     if (report.length() != 0) {
13233                         dbox.addText(dropboxTag, report);
13234                     }
13235                 }
13236             }.start();
13237             return;
13238         }
13239
13240         // System app batching:
13241         if (!bufferWasEmpty) {
13242             // An existing dropbox-writing thread is outstanding, so
13243             // we don't need to start it up.  The existing thread will
13244             // catch the buffer appends we just did.
13245             return;
13246         }
13247
13248         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13249         // (After this point, we shouldn't access AMS internal data structures.)
13250         new Thread("Error dump: " + dropboxTag) {
13251             @Override
13252             public void run() {
13253                 // 5 second sleep to let stacks arrive and be batched together
13254                 try {
13255                     Thread.sleep(5000);  // 5 seconds
13256                 } catch (InterruptedException e) {}
13257
13258                 String errorReport;
13259                 synchronized (mStrictModeBuffer) {
13260                     errorReport = mStrictModeBuffer.toString();
13261                     if (errorReport.length() == 0) {
13262                         return;
13263                     }
13264                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13265                     mStrictModeBuffer.trimToSize();
13266                 }
13267                 dbox.addText(dropboxTag, errorReport);
13268             }
13269         }.start();
13270     }
13271
13272     /**
13273      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13274      * @param app object of the crashing app, null for the system server
13275      * @param tag reported by the caller
13276      * @param system whether this wtf is coming from the system
13277      * @param crashInfo describing the context of the error
13278      * @return true if the process should exit immediately (WTF is fatal)
13279      */
13280     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13281             final ApplicationErrorReport.CrashInfo crashInfo) {
13282         final int callingUid = Binder.getCallingUid();
13283         final int callingPid = Binder.getCallingPid();
13284
13285         if (system) {
13286             // If this is coming from the system, we could very well have low-level
13287             // system locks held, so we want to do this all asynchronously.  And we
13288             // never want this to become fatal, so there is that too.
13289             mHandler.post(new Runnable() {
13290                 @Override public void run() {
13291                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13292                 }
13293             });
13294             return false;
13295         }
13296
13297         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13298                 crashInfo);
13299
13300         if (r != null && r.pid != Process.myPid() &&
13301                 Settings.Global.getInt(mContext.getContentResolver(),
13302                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13303             mAppErrors.crashApplication(r, crashInfo);
13304             return true;
13305         } else {
13306             return false;
13307         }
13308     }
13309
13310     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13311             final ApplicationErrorReport.CrashInfo crashInfo) {
13312         final ProcessRecord r = findAppProcess(app, "WTF");
13313         final String processName = app == null ? "system_server"
13314                 : (r == null ? "unknown" : r.processName);
13315
13316         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13317                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13318
13319         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13320
13321         return r;
13322     }
13323
13324     /**
13325      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13326      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13327      */
13328     private ProcessRecord findAppProcess(IBinder app, String reason) {
13329         if (app == null) {
13330             return null;
13331         }
13332
13333         synchronized (this) {
13334             final int NP = mProcessNames.getMap().size();
13335             for (int ip=0; ip<NP; ip++) {
13336                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13337                 final int NA = apps.size();
13338                 for (int ia=0; ia<NA; ia++) {
13339                     ProcessRecord p = apps.valueAt(ia);
13340                     if (p.thread != null && p.thread.asBinder() == app) {
13341                         return p;
13342                     }
13343                 }
13344             }
13345
13346             Slog.w(TAG, "Can't find mystery application for " + reason
13347                     + " from pid=" + Binder.getCallingPid()
13348                     + " uid=" + Binder.getCallingUid() + ": " + app);
13349             return null;
13350         }
13351     }
13352
13353     /**
13354      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13355      * to append various headers to the dropbox log text.
13356      */
13357     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13358             StringBuilder sb) {
13359         // Watchdog thread ends up invoking this function (with
13360         // a null ProcessRecord) to add the stack file to dropbox.
13361         // Do not acquire a lock on this (am) in such cases, as it
13362         // could cause a potential deadlock, if and when watchdog
13363         // is invoked due to unavailability of lock on am and it
13364         // would prevent watchdog from killing system_server.
13365         if (process == null) {
13366             sb.append("Process: ").append(processName).append("\n");
13367             return;
13368         }
13369         // Note: ProcessRecord 'process' is guarded by the service
13370         // instance.  (notably process.pkgList, which could otherwise change
13371         // concurrently during execution of this method)
13372         synchronized (this) {
13373             sb.append("Process: ").append(processName).append("\n");
13374             int flags = process.info.flags;
13375             IPackageManager pm = AppGlobals.getPackageManager();
13376             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13377             for (int ip=0; ip<process.pkgList.size(); ip++) {
13378                 String pkg = process.pkgList.keyAt(ip);
13379                 sb.append("Package: ").append(pkg);
13380                 try {
13381                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13382                     if (pi != null) {
13383                         sb.append(" v").append(pi.versionCode);
13384                         if (pi.versionName != null) {
13385                             sb.append(" (").append(pi.versionName).append(")");
13386                         }
13387                     }
13388                 } catch (RemoteException e) {
13389                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13390                 }
13391                 sb.append("\n");
13392             }
13393         }
13394     }
13395
13396     private static String processClass(ProcessRecord process) {
13397         if (process == null || process.pid == MY_PID) {
13398             return "system_server";
13399         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13400             return "system_app";
13401         } else {
13402             return "data_app";
13403         }
13404     }
13405
13406     private volatile long mWtfClusterStart;
13407     private volatile int mWtfClusterCount;
13408
13409     /**
13410      * Write a description of an error (crash, WTF, ANR) to the drop box.
13411      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13412      * @param process which caused the error, null means the system server
13413      * @param activity which triggered the error, null if unknown
13414      * @param parent activity related to the error, null if unknown
13415      * @param subject line related to the error, null if absent
13416      * @param report in long form describing the error, null if absent
13417      * @param logFile to include in the report, null if none
13418      * @param crashInfo giving an application stack trace, null if absent
13419      */
13420     public void addErrorToDropBox(String eventType,
13421             ProcessRecord process, String processName, ActivityRecord activity,
13422             ActivityRecord parent, String subject,
13423             final String report, final File logFile,
13424             final ApplicationErrorReport.CrashInfo crashInfo) {
13425         // NOTE -- this must never acquire the ActivityManagerService lock,
13426         // otherwise the watchdog may be prevented from resetting the system.
13427
13428         final String dropboxTag = processClass(process) + "_" + eventType;
13429         final DropBoxManager dbox = (DropBoxManager)
13430                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13431
13432         // Exit early if the dropbox isn't configured to accept this report type.
13433         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13434
13435         // Rate-limit how often we're willing to do the heavy lifting below to
13436         // collect and record logs; currently 5 logs per 10 second period.
13437         final long now = SystemClock.elapsedRealtime();
13438         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13439             mWtfClusterStart = now;
13440             mWtfClusterCount = 1;
13441         } else {
13442             if (mWtfClusterCount++ >= 5) return;
13443         }
13444
13445         final StringBuilder sb = new StringBuilder(1024);
13446         appendDropBoxProcessHeaders(process, processName, sb);
13447         if (process != null) {
13448             sb.append("Foreground: ")
13449                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13450                     .append("\n");
13451         }
13452         if (activity != null) {
13453             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13454         }
13455         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13456             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13457         }
13458         if (parent != null && parent != activity) {
13459             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13460         }
13461         if (subject != null) {
13462             sb.append("Subject: ").append(subject).append("\n");
13463         }
13464         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13465         if (Debug.isDebuggerConnected()) {
13466             sb.append("Debugger: Connected\n");
13467         }
13468         sb.append("\n");
13469
13470         // Do the rest in a worker thread to avoid blocking the caller on I/O
13471         // (After this point, we shouldn't access AMS internal data structures.)
13472         Thread worker = new Thread("Error dump: " + dropboxTag) {
13473             @Override
13474             public void run() {
13475                 if (report != null) {
13476                     sb.append(report);
13477                 }
13478                 if (logFile != null) {
13479                     try {
13480                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13481                                     "\n\n[[TRUNCATED]]"));
13482                     } catch (IOException e) {
13483                         Slog.e(TAG, "Error reading " + logFile, e);
13484                     }
13485                 }
13486                 if (crashInfo != null && crashInfo.stackTrace != null) {
13487                     sb.append(crashInfo.stackTrace);
13488                 }
13489
13490                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13491                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13492                 if (lines > 0) {
13493                     sb.append("\n");
13494
13495                     // Merge several logcat streams, and take the last N lines
13496                     InputStreamReader input = null;
13497                     try {
13498                         java.lang.Process logcat = new ProcessBuilder(
13499                                 "/system/bin/timeout", "-k", "15s", "10s",
13500                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13501                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13502                                         .redirectErrorStream(true).start();
13503
13504                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13505                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13506                         input = new InputStreamReader(logcat.getInputStream());
13507
13508                         int num;
13509                         char[] buf = new char[8192];
13510                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13511                     } catch (IOException e) {
13512                         Slog.e(TAG, "Error running logcat", e);
13513                     } finally {
13514                         if (input != null) try { input.close(); } catch (IOException e) {}
13515                     }
13516                 }
13517
13518                 dbox.addText(dropboxTag, sb.toString());
13519             }
13520         };
13521
13522         if (process == null) {
13523             // If process is null, we are being called from some internal code
13524             // and may be about to die -- run this synchronously.
13525             worker.run();
13526         } else {
13527             worker.start();
13528         }
13529     }
13530
13531     @Override
13532     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13533         enforceNotIsolatedCaller("getProcessesInErrorState");
13534         // assume our apps are happy - lazy create the list
13535         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13536
13537         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13538                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13539         int userId = UserHandle.getUserId(Binder.getCallingUid());
13540
13541         synchronized (this) {
13542
13543             // iterate across all processes
13544             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13545                 ProcessRecord app = mLruProcesses.get(i);
13546                 if (!allUsers && app.userId != userId) {
13547                     continue;
13548                 }
13549                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13550                     // This one's in trouble, so we'll generate a report for it
13551                     // crashes are higher priority (in case there's a crash *and* an anr)
13552                     ActivityManager.ProcessErrorStateInfo report = null;
13553                     if (app.crashing) {
13554                         report = app.crashingReport;
13555                     } else if (app.notResponding) {
13556                         report = app.notRespondingReport;
13557                     }
13558
13559                     if (report != null) {
13560                         if (errList == null) {
13561                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13562                         }
13563                         errList.add(report);
13564                     } else {
13565                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13566                                 " crashing = " + app.crashing +
13567                                 " notResponding = " + app.notResponding);
13568                     }
13569                 }
13570             }
13571         }
13572
13573         return errList;
13574     }
13575
13576     static int procStateToImportance(int procState, int memAdj,
13577             ActivityManager.RunningAppProcessInfo currApp) {
13578         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13579         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13580             currApp.lru = memAdj;
13581         } else {
13582             currApp.lru = 0;
13583         }
13584         return imp;
13585     }
13586
13587     private void fillInProcMemInfo(ProcessRecord app,
13588             ActivityManager.RunningAppProcessInfo outInfo) {
13589         outInfo.pid = app.pid;
13590         outInfo.uid = app.info.uid;
13591         if (mHeavyWeightProcess == app) {
13592             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13593         }
13594         if (app.persistent) {
13595             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13596         }
13597         if (app.activities.size() > 0) {
13598             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13599         }
13600         outInfo.lastTrimLevel = app.trimMemoryLevel;
13601         int adj = app.curAdj;
13602         int procState = app.curProcState;
13603         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13604         outInfo.importanceReasonCode = app.adjTypeCode;
13605         outInfo.processState = app.curProcState;
13606     }
13607
13608     @Override
13609     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13610         enforceNotIsolatedCaller("getRunningAppProcesses");
13611
13612         final int callingUid = Binder.getCallingUid();
13613
13614         // Lazy instantiation of list
13615         List<ActivityManager.RunningAppProcessInfo> runList = null;
13616         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13617                 callingUid) == PackageManager.PERMISSION_GRANTED;
13618         final int userId = UserHandle.getUserId(callingUid);
13619         final boolean allUids = isGetTasksAllowed(
13620                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13621
13622         synchronized (this) {
13623             // Iterate across all processes
13624             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13625                 ProcessRecord app = mLruProcesses.get(i);
13626                 if ((!allUsers && app.userId != userId)
13627                         || (!allUids && app.uid != callingUid)) {
13628                     continue;
13629                 }
13630                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13631                     // Generate process state info for running application
13632                     ActivityManager.RunningAppProcessInfo currApp =
13633                         new ActivityManager.RunningAppProcessInfo(app.processName,
13634                                 app.pid, app.getPackageList());
13635                     fillInProcMemInfo(app, currApp);
13636                     if (app.adjSource instanceof ProcessRecord) {
13637                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13638                         currApp.importanceReasonImportance =
13639                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13640                                         app.adjSourceProcState);
13641                     } else if (app.adjSource instanceof ActivityRecord) {
13642                         ActivityRecord r = (ActivityRecord)app.adjSource;
13643                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13644                     }
13645                     if (app.adjTarget instanceof ComponentName) {
13646                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13647                     }
13648                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13649                     //        + " lru=" + currApp.lru);
13650                     if (runList == null) {
13651                         runList = new ArrayList<>();
13652                     }
13653                     runList.add(currApp);
13654                 }
13655             }
13656         }
13657         return runList;
13658     }
13659
13660     @Override
13661     public List<ApplicationInfo> getRunningExternalApplications() {
13662         enforceNotIsolatedCaller("getRunningExternalApplications");
13663         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13664         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13665         if (runningApps != null && runningApps.size() > 0) {
13666             Set<String> extList = new HashSet<String>();
13667             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13668                 if (app.pkgList != null) {
13669                     for (String pkg : app.pkgList) {
13670                         extList.add(pkg);
13671                     }
13672                 }
13673             }
13674             IPackageManager pm = AppGlobals.getPackageManager();
13675             for (String pkg : extList) {
13676                 try {
13677                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13678                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13679                         retList.add(info);
13680                     }
13681                 } catch (RemoteException e) {
13682                 }
13683             }
13684         }
13685         return retList;
13686     }
13687
13688     @Override
13689     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13690         enforceNotIsolatedCaller("getMyMemoryState");
13691         synchronized (this) {
13692             ProcessRecord proc;
13693             synchronized (mPidsSelfLocked) {
13694                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13695             }
13696             fillInProcMemInfo(proc, outInfo);
13697         }
13698     }
13699
13700     @Override
13701     public int getMemoryTrimLevel() {
13702         enforceNotIsolatedCaller("getMyMemoryState");
13703         synchronized (this) {
13704             return mLastMemoryLevel;
13705         }
13706     }
13707
13708     @Override
13709     public void onShellCommand(FileDescriptor in, FileDescriptor out,
13710             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13711         (new ActivityManagerShellCommand(this, false)).exec(
13712                 this, in, out, err, args, resultReceiver);
13713     }
13714
13715     @Override
13716     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13717         if (checkCallingPermission(android.Manifest.permission.DUMP)
13718                 != PackageManager.PERMISSION_GRANTED) {
13719             pw.println("Permission Denial: can't dump ActivityManager from from pid="
13720                     + Binder.getCallingPid()
13721                     + ", uid=" + Binder.getCallingUid()
13722                     + " without permission "
13723                     + android.Manifest.permission.DUMP);
13724             return;
13725         }
13726
13727         boolean dumpAll = false;
13728         boolean dumpClient = false;
13729         String dumpPackage = null;
13730
13731         int opti = 0;
13732         while (opti < args.length) {
13733             String opt = args[opti];
13734             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13735                 break;
13736             }
13737             opti++;
13738             if ("-a".equals(opt)) {
13739                 dumpAll = true;
13740             } else if ("-c".equals(opt)) {
13741                 dumpClient = true;
13742             } else if ("-p".equals(opt)) {
13743                 if (opti < args.length) {
13744                     dumpPackage = args[opti];
13745                     opti++;
13746                 } else {
13747                     pw.println("Error: -p option requires package argument");
13748                     return;
13749                 }
13750                 dumpClient = true;
13751             } else if ("-h".equals(opt)) {
13752                 ActivityManagerShellCommand.dumpHelp(pw, true);
13753                 return;
13754             } else {
13755                 pw.println("Unknown argument: " + opt + "; use -h for help");
13756             }
13757         }
13758
13759         long origId = Binder.clearCallingIdentity();
13760         boolean more = false;
13761         // Is the caller requesting to dump a particular piece of data?
13762         if (opti < args.length) {
13763             String cmd = args[opti];
13764             opti++;
13765             if ("activities".equals(cmd) || "a".equals(cmd)) {
13766                 synchronized (this) {
13767                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13768                 }
13769             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13770                 synchronized (this) {
13771                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13772                 }
13773             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13774                 String[] newArgs;
13775                 String name;
13776                 if (opti >= args.length) {
13777                     name = null;
13778                     newArgs = EMPTY_STRING_ARRAY;
13779                 } else {
13780                     dumpPackage = args[opti];
13781                     opti++;
13782                     newArgs = new String[args.length - opti];
13783                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13784                             args.length - opti);
13785                 }
13786                 synchronized (this) {
13787                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13788                 }
13789             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13790                 String[] newArgs;
13791                 String name;
13792                 if (opti >= args.length) {
13793                     name = null;
13794                     newArgs = EMPTY_STRING_ARRAY;
13795                 } else {
13796                     dumpPackage = args[opti];
13797                     opti++;
13798                     newArgs = new String[args.length - opti];
13799                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13800                             args.length - opti);
13801                 }
13802                 synchronized (this) {
13803                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13804                 }
13805             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13806                 String[] newArgs;
13807                 String name;
13808                 if (opti >= args.length) {
13809                     name = null;
13810                     newArgs = EMPTY_STRING_ARRAY;
13811                 } else {
13812                     dumpPackage = args[opti];
13813                     opti++;
13814                     newArgs = new String[args.length - opti];
13815                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13816                             args.length - opti);
13817                 }
13818                 synchronized (this) {
13819                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13820                 }
13821             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13822                 synchronized (this) {
13823                     dumpOomLocked(fd, pw, args, opti, true);
13824                 }
13825             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13826                 synchronized (this) {
13827                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13828                 }
13829             } else if ("provider".equals(cmd)) {
13830                 String[] newArgs;
13831                 String name;
13832                 if (opti >= args.length) {
13833                     name = null;
13834                     newArgs = EMPTY_STRING_ARRAY;
13835                 } else {
13836                     name = args[opti];
13837                     opti++;
13838                     newArgs = new String[args.length - opti];
13839                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13840                 }
13841                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13842                     pw.println("No providers match: " + name);
13843                     pw.println("Use -h for help.");
13844                 }
13845             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13846                 synchronized (this) {
13847                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13848                 }
13849             } else if ("service".equals(cmd)) {
13850                 String[] newArgs;
13851                 String name;
13852                 if (opti >= args.length) {
13853                     name = null;
13854                     newArgs = EMPTY_STRING_ARRAY;
13855                 } else {
13856                     name = args[opti];
13857                     opti++;
13858                     newArgs = new String[args.length - opti];
13859                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13860                             args.length - opti);
13861                 }
13862                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13863                     pw.println("No services match: " + name);
13864                     pw.println("Use -h for help.");
13865                 }
13866             } else if ("package".equals(cmd)) {
13867                 String[] newArgs;
13868                 if (opti >= args.length) {
13869                     pw.println("package: no package name specified");
13870                     pw.println("Use -h for help.");
13871                 } else {
13872                     dumpPackage = args[opti];
13873                     opti++;
13874                     newArgs = new String[args.length - opti];
13875                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13876                             args.length - opti);
13877                     args = newArgs;
13878                     opti = 0;
13879                     more = true;
13880                 }
13881             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13882                 synchronized (this) {
13883                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13884                 }
13885             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13886                 if (dumpClient) {
13887                     ActiveServices.ServiceDumper dumper;
13888                     synchronized (this) {
13889                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13890                                 dumpPackage);
13891                     }
13892                     dumper.dumpWithClient();
13893                 } else {
13894                     synchronized (this) {
13895                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13896                                 dumpPackage).dumpLocked();
13897                     }
13898                 }
13899             } else if ("locks".equals(cmd)) {
13900                 LockGuard.dump(fd, pw, args);
13901             } else {
13902                 // Dumping a single activity?
13903                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13904                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13905                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13906                     if (res < 0) {
13907                         pw.println("Bad activity command, or no activities match: " + cmd);
13908                         pw.println("Use -h for help.");
13909                     }
13910                 }
13911             }
13912             if (!more) {
13913                 Binder.restoreCallingIdentity(origId);
13914                 return;
13915             }
13916         }
13917
13918         // No piece of data specified, dump everything.
13919         if (dumpClient) {
13920             ActiveServices.ServiceDumper sdumper;
13921             synchronized (this) {
13922                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13923                 pw.println();
13924                 if (dumpAll) {
13925                     pw.println("-------------------------------------------------------------------------------");
13926                 }
13927                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13928                 pw.println();
13929                 if (dumpAll) {
13930                     pw.println("-------------------------------------------------------------------------------");
13931                 }
13932                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13933                 pw.println();
13934                 if (dumpAll) {
13935                     pw.println("-------------------------------------------------------------------------------");
13936                 }
13937                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13938                 pw.println();
13939                 if (dumpAll) {
13940                     pw.println("-------------------------------------------------------------------------------");
13941                 }
13942                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13943                         dumpPackage);
13944             }
13945             sdumper.dumpWithClient();
13946             pw.println();
13947             synchronized (this) {
13948                 if (dumpAll) {
13949                     pw.println("-------------------------------------------------------------------------------");
13950                 }
13951                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13952                 pw.println();
13953                 if (dumpAll) {
13954                     pw.println("-------------------------------------------------------------------------------");
13955                 }
13956                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13957                 if (mAssociations.size() > 0) {
13958                     pw.println();
13959                     if (dumpAll) {
13960                         pw.println("-------------------------------------------------------------------------------");
13961                     }
13962                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13963                 }
13964                 pw.println();
13965                 if (dumpAll) {
13966                     pw.println("-------------------------------------------------------------------------------");
13967                 }
13968                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13969             }
13970
13971         } else {
13972             synchronized (this) {
13973                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13974                 pw.println();
13975                 if (dumpAll) {
13976                     pw.println("-------------------------------------------------------------------------------");
13977                 }
13978                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13979                 pw.println();
13980                 if (dumpAll) {
13981                     pw.println("-------------------------------------------------------------------------------");
13982                 }
13983                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13984                 pw.println();
13985                 if (dumpAll) {
13986                     pw.println("-------------------------------------------------------------------------------");
13987                 }
13988                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13989                 pw.println();
13990                 if (dumpAll) {
13991                     pw.println("-------------------------------------------------------------------------------");
13992                 }
13993                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13994                         .dumpLocked();
13995                 pw.println();
13996                 if (dumpAll) {
13997                     pw.println("-------------------------------------------------------------------------------");
13998                 }
13999                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14000                 pw.println();
14001                 if (dumpAll) {
14002                     pw.println("-------------------------------------------------------------------------------");
14003                 }
14004                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14005                 if (mAssociations.size() > 0) {
14006                     pw.println();
14007                     if (dumpAll) {
14008                         pw.println("-------------------------------------------------------------------------------");
14009                     }
14010                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14011                 }
14012                 pw.println();
14013                 if (dumpAll) {
14014                     pw.println("-------------------------------------------------------------------------------");
14015                 }
14016                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14017             }
14018         }
14019         Binder.restoreCallingIdentity(origId);
14020     }
14021
14022     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14023             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14024         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14025
14026         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14027                 dumpPackage);
14028         boolean needSep = printedAnything;
14029
14030         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14031                 dumpPackage, needSep, "  mFocusedActivity: ");
14032         if (printed) {
14033             printedAnything = true;
14034             needSep = false;
14035         }
14036
14037         if (dumpPackage == null) {
14038             if (needSep) {
14039                 pw.println();
14040             }
14041             needSep = true;
14042             printedAnything = true;
14043             mStackSupervisor.dump(pw, "  ");
14044         }
14045
14046         if (!printedAnything) {
14047             pw.println("  (nothing)");
14048         }
14049     }
14050
14051     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14052             int opti, boolean dumpAll, String dumpPackage) {
14053         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14054
14055         boolean printedAnything = false;
14056
14057         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14058             boolean printedHeader = false;
14059
14060             final int N = mRecentTasks.size();
14061             for (int i=0; i<N; i++) {
14062                 TaskRecord tr = mRecentTasks.get(i);
14063                 if (dumpPackage != null) {
14064                     if (tr.realActivity == null ||
14065                             !dumpPackage.equals(tr.realActivity)) {
14066                         continue;
14067                     }
14068                 }
14069                 if (!printedHeader) {
14070                     pw.println("  Recent tasks:");
14071                     printedHeader = true;
14072                     printedAnything = true;
14073                 }
14074                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14075                         pw.println(tr);
14076                 if (dumpAll) {
14077                     mRecentTasks.get(i).dump(pw, "    ");
14078                 }
14079             }
14080         }
14081
14082         if (!printedAnything) {
14083             pw.println("  (nothing)");
14084         }
14085     }
14086
14087     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14088             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14089         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14090
14091         int dumpUid = 0;
14092         if (dumpPackage != null) {
14093             IPackageManager pm = AppGlobals.getPackageManager();
14094             try {
14095                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14096             } catch (RemoteException e) {
14097             }
14098         }
14099
14100         boolean printedAnything = false;
14101
14102         final long now = SystemClock.uptimeMillis();
14103
14104         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14105             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14106                     = mAssociations.valueAt(i1);
14107             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14108                 SparseArray<ArrayMap<String, Association>> sourceUids
14109                         = targetComponents.valueAt(i2);
14110                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14111                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14112                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14113                         Association ass = sourceProcesses.valueAt(i4);
14114                         if (dumpPackage != null) {
14115                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14116                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14117                                 continue;
14118                             }
14119                         }
14120                         printedAnything = true;
14121                         pw.print("  ");
14122                         pw.print(ass.mTargetProcess);
14123                         pw.print("/");
14124                         UserHandle.formatUid(pw, ass.mTargetUid);
14125                         pw.print(" <- ");
14126                         pw.print(ass.mSourceProcess);
14127                         pw.print("/");
14128                         UserHandle.formatUid(pw, ass.mSourceUid);
14129                         pw.println();
14130                         pw.print("    via ");
14131                         pw.print(ass.mTargetComponent.flattenToShortString());
14132                         pw.println();
14133                         pw.print("    ");
14134                         long dur = ass.mTime;
14135                         if (ass.mNesting > 0) {
14136                             dur += now - ass.mStartTime;
14137                         }
14138                         TimeUtils.formatDuration(dur, pw);
14139                         pw.print(" (");
14140                         pw.print(ass.mCount);
14141                         pw.print(" times)");
14142                         pw.print("  ");
14143                         for (int i=0; i<ass.mStateTimes.length; i++) {
14144                             long amt = ass.mStateTimes[i];
14145                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14146                                 amt += now - ass.mLastStateUptime;
14147                             }
14148                             if (amt != 0) {
14149                                 pw.print(" ");
14150                                 pw.print(ProcessList.makeProcStateString(
14151                                             i + ActivityManager.MIN_PROCESS_STATE));
14152                                 pw.print("=");
14153                                 TimeUtils.formatDuration(amt, pw);
14154                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14155                                     pw.print("*");
14156                                 }
14157                             }
14158                         }
14159                         pw.println();
14160                         if (ass.mNesting > 0) {
14161                             pw.print("    Currently active: ");
14162                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14163                             pw.println();
14164                         }
14165                     }
14166                 }
14167             }
14168
14169         }
14170
14171         if (!printedAnything) {
14172             pw.println("  (nothing)");
14173         }
14174     }
14175
14176     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14177             String header, boolean needSep) {
14178         boolean printed = false;
14179         int whichAppId = -1;
14180         if (dumpPackage != null) {
14181             try {
14182                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14183                         dumpPackage, 0);
14184                 whichAppId = UserHandle.getAppId(info.uid);
14185             } catch (NameNotFoundException e) {
14186                 e.printStackTrace();
14187             }
14188         }
14189         for (int i=0; i<uids.size(); i++) {
14190             UidRecord uidRec = uids.valueAt(i);
14191             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14192                 continue;
14193             }
14194             if (!printed) {
14195                 printed = true;
14196                 if (needSep) {
14197                     pw.println();
14198                 }
14199                 pw.print("  ");
14200                 pw.println(header);
14201                 needSep = true;
14202             }
14203             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14204             pw.print(": "); pw.println(uidRec);
14205         }
14206         return printed;
14207     }
14208
14209     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14210             int opti, boolean dumpAll, String dumpPackage) {
14211         boolean needSep = false;
14212         boolean printedAnything = false;
14213         int numPers = 0;
14214
14215         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14216
14217         if (dumpAll) {
14218             final int NP = mProcessNames.getMap().size();
14219             for (int ip=0; ip<NP; ip++) {
14220                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14221                 final int NA = procs.size();
14222                 for (int ia=0; ia<NA; ia++) {
14223                     ProcessRecord r = procs.valueAt(ia);
14224                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14225                         continue;
14226                     }
14227                     if (!needSep) {
14228                         pw.println("  All known processes:");
14229                         needSep = true;
14230                         printedAnything = true;
14231                     }
14232                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14233                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14234                         pw.print(" "); pw.println(r);
14235                     r.dump(pw, "    ");
14236                     if (r.persistent) {
14237                         numPers++;
14238                     }
14239                 }
14240             }
14241         }
14242
14243         if (mIsolatedProcesses.size() > 0) {
14244             boolean printed = false;
14245             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14246                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14247                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14248                     continue;
14249                 }
14250                 if (!printed) {
14251                     if (needSep) {
14252                         pw.println();
14253                     }
14254                     pw.println("  Isolated process list (sorted by uid):");
14255                     printedAnything = true;
14256                     printed = true;
14257                     needSep = true;
14258                 }
14259                 pw.println(String.format("%sIsolated #%2d: %s",
14260                         "    ", i, r.toString()));
14261             }
14262         }
14263
14264         if (mActiveUids.size() > 0) {
14265             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14266                 printedAnything = needSep = true;
14267             }
14268         }
14269         if (mValidateUids.size() > 0) {
14270             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14271                 printedAnything = needSep = true;
14272             }
14273         }
14274
14275         if (mLruProcesses.size() > 0) {
14276             if (needSep) {
14277                 pw.println();
14278             }
14279             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14280                     pw.print(" total, non-act at ");
14281                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14282                     pw.print(", non-svc at ");
14283                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14284                     pw.println("):");
14285             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14286             needSep = true;
14287             printedAnything = true;
14288         }
14289
14290         if (dumpAll || dumpPackage != null) {
14291             synchronized (mPidsSelfLocked) {
14292                 boolean printed = false;
14293                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14294                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14295                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14296                         continue;
14297                     }
14298                     if (!printed) {
14299                         if (needSep) pw.println();
14300                         needSep = true;
14301                         pw.println("  PID mappings:");
14302                         printed = true;
14303                         printedAnything = true;
14304                     }
14305                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14306                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14307                 }
14308             }
14309         }
14310
14311         if (mForegroundProcesses.size() > 0) {
14312             synchronized (mPidsSelfLocked) {
14313                 boolean printed = false;
14314                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14315                     ProcessRecord r = mPidsSelfLocked.get(
14316                             mForegroundProcesses.valueAt(i).pid);
14317                     if (dumpPackage != null && (r == null
14318                             || !r.pkgList.containsKey(dumpPackage))) {
14319                         continue;
14320                     }
14321                     if (!printed) {
14322                         if (needSep) pw.println();
14323                         needSep = true;
14324                         pw.println("  Foreground Processes:");
14325                         printed = true;
14326                         printedAnything = true;
14327                     }
14328                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14329                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14330                 }
14331             }
14332         }
14333
14334         if (mPersistentStartingProcesses.size() > 0) {
14335             if (needSep) pw.println();
14336             needSep = true;
14337             printedAnything = true;
14338             pw.println("  Persisent processes that are starting:");
14339             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14340                     "Starting Norm", "Restarting PERS", dumpPackage);
14341         }
14342
14343         if (mRemovedProcesses.size() > 0) {
14344             if (needSep) pw.println();
14345             needSep = true;
14346             printedAnything = true;
14347             pw.println("  Processes that are being removed:");
14348             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14349                     "Removed Norm", "Removed PERS", dumpPackage);
14350         }
14351
14352         if (mProcessesOnHold.size() > 0) {
14353             if (needSep) pw.println();
14354             needSep = true;
14355             printedAnything = true;
14356             pw.println("  Processes that are on old until the system is ready:");
14357             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14358                     "OnHold Norm", "OnHold PERS", dumpPackage);
14359         }
14360
14361         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14362
14363         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14364         if (needSep) {
14365             printedAnything = true;
14366         }
14367
14368         if (dumpPackage == null) {
14369             pw.println();
14370             needSep = false;
14371             mUserController.dump(pw, dumpAll);
14372         }
14373         if (mHomeProcess != null && (dumpPackage == null
14374                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14375             if (needSep) {
14376                 pw.println();
14377                 needSep = false;
14378             }
14379             pw.println("  mHomeProcess: " + mHomeProcess);
14380         }
14381         if (mPreviousProcess != null && (dumpPackage == null
14382                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14383             if (needSep) {
14384                 pw.println();
14385                 needSep = false;
14386             }
14387             pw.println("  mPreviousProcess: " + mPreviousProcess);
14388         }
14389         if (dumpAll) {
14390             StringBuilder sb = new StringBuilder(128);
14391             sb.append("  mPreviousProcessVisibleTime: ");
14392             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14393             pw.println(sb);
14394         }
14395         if (mHeavyWeightProcess != null && (dumpPackage == null
14396                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14397             if (needSep) {
14398                 pw.println();
14399                 needSep = false;
14400             }
14401             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14402         }
14403         if (dumpPackage == null) {
14404             pw.println("  mConfiguration: " + mConfiguration);
14405         }
14406         if (dumpAll) {
14407             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14408             if (mCompatModePackages.getPackages().size() > 0) {
14409                 boolean printed = false;
14410                 for (Map.Entry<String, Integer> entry
14411                         : mCompatModePackages.getPackages().entrySet()) {
14412                     String pkg = entry.getKey();
14413                     int mode = entry.getValue();
14414                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14415                         continue;
14416                     }
14417                     if (!printed) {
14418                         pw.println("  mScreenCompatPackages:");
14419                         printed = true;
14420                     }
14421                     pw.print("    "); pw.print(pkg); pw.print(": ");
14422                             pw.print(mode); pw.println();
14423                 }
14424             }
14425         }
14426         if (dumpPackage == null) {
14427             pw.println("  mWakefulness="
14428                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14429             pw.println("  mSleepTokens=" + mSleepTokens);
14430             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14431                     + lockScreenShownToString());
14432             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14433             if (mRunningVoice != null) {
14434                 pw.println("  mRunningVoice=" + mRunningVoice);
14435                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14436             }
14437         }
14438         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14439                 || mOrigWaitForDebugger) {
14440             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14441                     || dumpPackage.equals(mOrigDebugApp)) {
14442                 if (needSep) {
14443                     pw.println();
14444                     needSep = false;
14445                 }
14446                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14447                         + " mDebugTransient=" + mDebugTransient
14448                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14449             }
14450         }
14451         if (mCurAppTimeTracker != null) {
14452             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14453         }
14454         if (mMemWatchProcesses.getMap().size() > 0) {
14455             pw.println("  Mem watch processes:");
14456             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14457                     = mMemWatchProcesses.getMap();
14458             for (int i=0; i<procs.size(); i++) {
14459                 final String proc = procs.keyAt(i);
14460                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14461                 for (int j=0; j<uids.size(); j++) {
14462                     if (needSep) {
14463                         pw.println();
14464                         needSep = false;
14465                     }
14466                     StringBuilder sb = new StringBuilder();
14467                     sb.append("    ").append(proc).append('/');
14468                     UserHandle.formatUid(sb, uids.keyAt(j));
14469                     Pair<Long, String> val = uids.valueAt(j);
14470                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14471                     if (val.second != null) {
14472                         sb.append(", report to ").append(val.second);
14473                     }
14474                     pw.println(sb.toString());
14475                 }
14476             }
14477             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14478             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14479             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14480                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14481         }
14482         if (mTrackAllocationApp != null) {
14483             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14484                 if (needSep) {
14485                     pw.println();
14486                     needSep = false;
14487                 }
14488                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14489             }
14490         }
14491         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14492                 || mProfileFd != null) {
14493             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14494                 if (needSep) {
14495                     pw.println();
14496                     needSep = false;
14497                 }
14498                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14499                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14500                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14501                         + mAutoStopProfiler);
14502                 pw.println("  mProfileType=" + mProfileType);
14503             }
14504         }
14505         if (mNativeDebuggingApp != null) {
14506             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14507                 if (needSep) {
14508                     pw.println();
14509                     needSep = false;
14510                 }
14511                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14512             }
14513         }
14514         if (dumpPackage == null) {
14515             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14516                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14517                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14518             }
14519             if (mController != null) {
14520                 pw.println("  mController=" + mController
14521                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14522             }
14523             if (dumpAll) {
14524                 pw.println("  Total persistent processes: " + numPers);
14525                 pw.println("  mProcessesReady=" + mProcessesReady
14526                         + " mSystemReady=" + mSystemReady
14527                         + " mBooted=" + mBooted
14528                         + " mFactoryTest=" + mFactoryTest);
14529                 pw.println("  mBooting=" + mBooting
14530                         + " mCallFinishBooting=" + mCallFinishBooting
14531                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14532                 pw.print("  mLastPowerCheckRealtime=");
14533                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14534                         pw.println("");
14535                 pw.print("  mLastPowerCheckUptime=");
14536                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14537                         pw.println("");
14538                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14539                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14540                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14541                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14542                         + " (" + mLruProcesses.size() + " total)"
14543                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14544                         + " mNumServiceProcs=" + mNumServiceProcs
14545                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14546                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14547                         + " mLastMemoryLevel=" + mLastMemoryLevel
14548                         + " mLastNumProcesses=" + mLastNumProcesses);
14549                 long now = SystemClock.uptimeMillis();
14550                 pw.print("  mLastIdleTime=");
14551                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14552                         pw.print(" mLowRamSinceLastIdle=");
14553                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14554                         pw.println();
14555             }
14556         }
14557
14558         if (!printedAnything) {
14559             pw.println("  (nothing)");
14560         }
14561     }
14562
14563     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14564             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14565         if (mProcessesToGc.size() > 0) {
14566             boolean printed = false;
14567             long now = SystemClock.uptimeMillis();
14568             for (int i=0; i<mProcessesToGc.size(); i++) {
14569                 ProcessRecord proc = mProcessesToGc.get(i);
14570                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14571                     continue;
14572                 }
14573                 if (!printed) {
14574                     if (needSep) pw.println();
14575                     needSep = true;
14576                     pw.println("  Processes that are waiting to GC:");
14577                     printed = true;
14578                 }
14579                 pw.print("    Process "); pw.println(proc);
14580                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14581                         pw.print(", last gced=");
14582                         pw.print(now-proc.lastRequestedGc);
14583                         pw.print(" ms ago, last lowMem=");
14584                         pw.print(now-proc.lastLowMemory);
14585                         pw.println(" ms ago");
14586
14587             }
14588         }
14589         return needSep;
14590     }
14591
14592     void printOomLevel(PrintWriter pw, String name, int adj) {
14593         pw.print("    ");
14594         if (adj >= 0) {
14595             pw.print(' ');
14596             if (adj < 10) pw.print(' ');
14597         } else {
14598             if (adj > -10) pw.print(' ');
14599         }
14600         pw.print(adj);
14601         pw.print(": ");
14602         pw.print(name);
14603         pw.print(" (");
14604         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14605         pw.println(")");
14606     }
14607
14608     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14609             int opti, boolean dumpAll) {
14610         boolean needSep = false;
14611
14612         if (mLruProcesses.size() > 0) {
14613             if (needSep) pw.println();
14614             needSep = true;
14615             pw.println("  OOM levels:");
14616             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14617             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14618             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14619             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14620             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14621             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14622             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14623             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14624             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14625             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14626             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14627             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14628             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14629             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14630
14631             if (needSep) pw.println();
14632             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14633                     pw.print(" total, non-act at ");
14634                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14635                     pw.print(", non-svc at ");
14636                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14637                     pw.println("):");
14638             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14639             needSep = true;
14640         }
14641
14642         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14643
14644         pw.println();
14645         pw.println("  mHomeProcess: " + mHomeProcess);
14646         pw.println("  mPreviousProcess: " + mPreviousProcess);
14647         if (mHeavyWeightProcess != null) {
14648             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14649         }
14650
14651         return true;
14652     }
14653
14654     /**
14655      * There are three ways to call this:
14656      *  - no provider specified: dump all the providers
14657      *  - a flattened component name that matched an existing provider was specified as the
14658      *    first arg: dump that one provider
14659      *  - the first arg isn't the flattened component name of an existing provider:
14660      *    dump all providers whose component contains the first arg as a substring
14661      */
14662     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14663             int opti, boolean dumpAll) {
14664         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14665     }
14666
14667     static class ItemMatcher {
14668         ArrayList<ComponentName> components;
14669         ArrayList<String> strings;
14670         ArrayList<Integer> objects;
14671         boolean all;
14672
14673         ItemMatcher() {
14674             all = true;
14675         }
14676
14677         void build(String name) {
14678             ComponentName componentName = ComponentName.unflattenFromString(name);
14679             if (componentName != null) {
14680                 if (components == null) {
14681                     components = new ArrayList<ComponentName>();
14682                 }
14683                 components.add(componentName);
14684                 all = false;
14685             } else {
14686                 int objectId = 0;
14687                 // Not a '/' separated full component name; maybe an object ID?
14688                 try {
14689                     objectId = Integer.parseInt(name, 16);
14690                     if (objects == null) {
14691                         objects = new ArrayList<Integer>();
14692                     }
14693                     objects.add(objectId);
14694                     all = false;
14695                 } catch (RuntimeException e) {
14696                     // Not an integer; just do string match.
14697                     if (strings == null) {
14698                         strings = new ArrayList<String>();
14699                     }
14700                     strings.add(name);
14701                     all = false;
14702                 }
14703             }
14704         }
14705
14706         int build(String[] args, int opti) {
14707             for (; opti<args.length; opti++) {
14708                 String name = args[opti];
14709                 if ("--".equals(name)) {
14710                     return opti+1;
14711                 }
14712                 build(name);
14713             }
14714             return opti;
14715         }
14716
14717         boolean match(Object object, ComponentName comp) {
14718             if (all) {
14719                 return true;
14720             }
14721             if (components != null) {
14722                 for (int i=0; i<components.size(); i++) {
14723                     if (components.get(i).equals(comp)) {
14724                         return true;
14725                     }
14726                 }
14727             }
14728             if (objects != null) {
14729                 for (int i=0; i<objects.size(); i++) {
14730                     if (System.identityHashCode(object) == objects.get(i)) {
14731                         return true;
14732                     }
14733                 }
14734             }
14735             if (strings != null) {
14736                 String flat = comp.flattenToString();
14737                 for (int i=0; i<strings.size(); i++) {
14738                     if (flat.contains(strings.get(i))) {
14739                         return true;
14740                     }
14741                 }
14742             }
14743             return false;
14744         }
14745     }
14746
14747     /**
14748      * There are three things that cmd can be:
14749      *  - a flattened component name that matches an existing activity
14750      *  - the cmd arg isn't the flattened component name of an existing activity:
14751      *    dump all activity whose component contains the cmd as a substring
14752      *  - A hex number of the ActivityRecord object instance.
14753      */
14754     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14755             int opti, boolean dumpAll) {
14756         ArrayList<ActivityRecord> activities;
14757
14758         synchronized (this) {
14759             activities = mStackSupervisor.getDumpActivitiesLocked(name);
14760         }
14761
14762         if (activities.size() <= 0) {
14763             return false;
14764         }
14765
14766         String[] newArgs = new String[args.length - opti];
14767         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14768
14769         TaskRecord lastTask = null;
14770         boolean needSep = false;
14771         for (int i=activities.size()-1; i>=0; i--) {
14772             ActivityRecord r = activities.get(i);
14773             if (needSep) {
14774                 pw.println();
14775             }
14776             needSep = true;
14777             synchronized (this) {
14778                 if (lastTask != r.task) {
14779                     lastTask = r.task;
14780                     pw.print("TASK "); pw.print(lastTask.affinity);
14781                             pw.print(" id="); pw.println(lastTask.taskId);
14782                     if (dumpAll) {
14783                         lastTask.dump(pw, "  ");
14784                     }
14785                 }
14786             }
14787             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14788         }
14789         return true;
14790     }
14791
14792     /**
14793      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14794      * there is a thread associated with the activity.
14795      */
14796     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14797             final ActivityRecord r, String[] args, boolean dumpAll) {
14798         String innerPrefix = prefix + "  ";
14799         synchronized (this) {
14800             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14801                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14802                     pw.print(" pid=");
14803                     if (r.app != null) pw.println(r.app.pid);
14804                     else pw.println("(not running)");
14805             if (dumpAll) {
14806                 r.dump(pw, innerPrefix);
14807             }
14808         }
14809         if (r.app != null && r.app.thread != null) {
14810             // flush anything that is already in the PrintWriter since the thread is going
14811             // to write to the file descriptor directly
14812             pw.flush();
14813             try {
14814                 TransferPipe tp = new TransferPipe();
14815                 try {
14816                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14817                             r.appToken, innerPrefix, args);
14818                     tp.go(fd);
14819                 } finally {
14820                     tp.kill();
14821                 }
14822             } catch (IOException e) {
14823                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14824             } catch (RemoteException e) {
14825                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14826             }
14827         }
14828     }
14829
14830     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14831             int opti, boolean dumpAll, String dumpPackage) {
14832         boolean needSep = false;
14833         boolean onlyHistory = false;
14834         boolean printedAnything = false;
14835
14836         if ("history".equals(dumpPackage)) {
14837             if (opti < args.length && "-s".equals(args[opti])) {
14838                 dumpAll = false;
14839             }
14840             onlyHistory = true;
14841             dumpPackage = null;
14842         }
14843
14844         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14845         if (!onlyHistory && dumpAll) {
14846             if (mRegisteredReceivers.size() > 0) {
14847                 boolean printed = false;
14848                 Iterator it = mRegisteredReceivers.values().iterator();
14849                 while (it.hasNext()) {
14850                     ReceiverList r = (ReceiverList)it.next();
14851                     if (dumpPackage != null && (r.app == null ||
14852                             !dumpPackage.equals(r.app.info.packageName))) {
14853                         continue;
14854                     }
14855                     if (!printed) {
14856                         pw.println("  Registered Receivers:");
14857                         needSep = true;
14858                         printed = true;
14859                         printedAnything = true;
14860                     }
14861                     pw.print("  * "); pw.println(r);
14862                     r.dump(pw, "    ");
14863                 }
14864             }
14865
14866             if (mReceiverResolver.dump(pw, needSep ?
14867                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14868                     "    ", dumpPackage, false, false)) {
14869                 needSep = true;
14870                 printedAnything = true;
14871             }
14872         }
14873
14874         for (BroadcastQueue q : mBroadcastQueues) {
14875             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14876             printedAnything |= needSep;
14877         }
14878
14879         needSep = true;
14880
14881         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14882             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14883                 if (needSep) {
14884                     pw.println();
14885                 }
14886                 needSep = true;
14887                 printedAnything = true;
14888                 pw.print("  Sticky broadcasts for user ");
14889                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14890                 StringBuilder sb = new StringBuilder(128);
14891                 for (Map.Entry<String, ArrayList<Intent>> ent
14892                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14893                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14894                     if (dumpAll) {
14895                         pw.println(":");
14896                         ArrayList<Intent> intents = ent.getValue();
14897                         final int N = intents.size();
14898                         for (int i=0; i<N; i++) {
14899                             sb.setLength(0);
14900                             sb.append("    Intent: ");
14901                             intents.get(i).toShortString(sb, false, true, false, false);
14902                             pw.println(sb.toString());
14903                             Bundle bundle = intents.get(i).getExtras();
14904                             if (bundle != null) {
14905                                 pw.print("      ");
14906                                 pw.println(bundle.toString());
14907                             }
14908                         }
14909                     } else {
14910                         pw.println("");
14911                     }
14912                 }
14913             }
14914         }
14915
14916         if (!onlyHistory && dumpAll) {
14917             pw.println();
14918             for (BroadcastQueue queue : mBroadcastQueues) {
14919                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14920                         + queue.mBroadcastsScheduled);
14921             }
14922             pw.println("  mHandler:");
14923             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14924             needSep = true;
14925             printedAnything = true;
14926         }
14927
14928         if (!printedAnything) {
14929             pw.println("  (nothing)");
14930         }
14931     }
14932
14933     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14934             int opti, boolean dumpAll, String dumpPackage) {
14935         boolean needSep;
14936         boolean printedAnything = false;
14937
14938         ItemMatcher matcher = new ItemMatcher();
14939         matcher.build(args, opti);
14940
14941         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14942
14943         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14944         printedAnything |= needSep;
14945
14946         if (mLaunchingProviders.size() > 0) {
14947             boolean printed = false;
14948             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14949                 ContentProviderRecord r = mLaunchingProviders.get(i);
14950                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14951                     continue;
14952                 }
14953                 if (!printed) {
14954                     if (needSep) pw.println();
14955                     needSep = true;
14956                     pw.println("  Launching content providers:");
14957                     printed = true;
14958                     printedAnything = true;
14959                 }
14960                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14961                         pw.println(r);
14962             }
14963         }
14964
14965         if (!printedAnything) {
14966             pw.println("  (nothing)");
14967         }
14968     }
14969
14970     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14971             int opti, boolean dumpAll, String dumpPackage) {
14972         boolean needSep = false;
14973         boolean printedAnything = false;
14974
14975         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14976
14977         if (mGrantedUriPermissions.size() > 0) {
14978             boolean printed = false;
14979             int dumpUid = -2;
14980             if (dumpPackage != null) {
14981                 try {
14982                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14983                             MATCH_UNINSTALLED_PACKAGES, 0);
14984                 } catch (NameNotFoundException e) {
14985                     dumpUid = -1;
14986                 }
14987             }
14988             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14989                 int uid = mGrantedUriPermissions.keyAt(i);
14990                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14991                     continue;
14992                 }
14993                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14994                 if (!printed) {
14995                     if (needSep) pw.println();
14996                     needSep = true;
14997                     pw.println("  Granted Uri Permissions:");
14998                     printed = true;
14999                     printedAnything = true;
15000                 }
15001                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15002                 for (UriPermission perm : perms.values()) {
15003                     pw.print("    "); pw.println(perm);
15004                     if (dumpAll) {
15005                         perm.dump(pw, "      ");
15006                     }
15007                 }
15008             }
15009         }
15010
15011         if (!printedAnything) {
15012             pw.println("  (nothing)");
15013         }
15014     }
15015
15016     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15017             int opti, boolean dumpAll, String dumpPackage) {
15018         boolean printed = false;
15019
15020         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15021
15022         if (mIntentSenderRecords.size() > 0) {
15023             Iterator<WeakReference<PendingIntentRecord>> it
15024                     = mIntentSenderRecords.values().iterator();
15025             while (it.hasNext()) {
15026                 WeakReference<PendingIntentRecord> ref = it.next();
15027                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15028                 if (dumpPackage != null && (rec == null
15029                         || !dumpPackage.equals(rec.key.packageName))) {
15030                     continue;
15031                 }
15032                 printed = true;
15033                 if (rec != null) {
15034                     pw.print("  * "); pw.println(rec);
15035                     if (dumpAll) {
15036                         rec.dump(pw, "    ");
15037                     }
15038                 } else {
15039                     pw.print("  * "); pw.println(ref);
15040                 }
15041             }
15042         }
15043
15044         if (!printed) {
15045             pw.println("  (nothing)");
15046         }
15047     }
15048
15049     private static final int dumpProcessList(PrintWriter pw,
15050             ActivityManagerService service, List list,
15051             String prefix, String normalLabel, String persistentLabel,
15052             String dumpPackage) {
15053         int numPers = 0;
15054         final int N = list.size()-1;
15055         for (int i=N; i>=0; i--) {
15056             ProcessRecord r = (ProcessRecord)list.get(i);
15057             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15058                 continue;
15059             }
15060             pw.println(String.format("%s%s #%2d: %s",
15061                     prefix, (r.persistent ? persistentLabel : normalLabel),
15062                     i, r.toString()));
15063             if (r.persistent) {
15064                 numPers++;
15065             }
15066         }
15067         return numPers;
15068     }
15069
15070     private static final boolean dumpProcessOomList(PrintWriter pw,
15071             ActivityManagerService service, List<ProcessRecord> origList,
15072             String prefix, String normalLabel, String persistentLabel,
15073             boolean inclDetails, String dumpPackage) {
15074
15075         ArrayList<Pair<ProcessRecord, Integer>> list
15076                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15077         for (int i=0; i<origList.size(); i++) {
15078             ProcessRecord r = origList.get(i);
15079             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15080                 continue;
15081             }
15082             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15083         }
15084
15085         if (list.size() <= 0) {
15086             return false;
15087         }
15088
15089         Comparator<Pair<ProcessRecord, Integer>> comparator
15090                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15091             @Override
15092             public int compare(Pair<ProcessRecord, Integer> object1,
15093                     Pair<ProcessRecord, Integer> object2) {
15094                 if (object1.first.setAdj != object2.first.setAdj) {
15095                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15096                 }
15097                 if (object1.first.setProcState != object2.first.setProcState) {
15098                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15099                 }
15100                 if (object1.second.intValue() != object2.second.intValue()) {
15101                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15102                 }
15103                 return 0;
15104             }
15105         };
15106
15107         Collections.sort(list, comparator);
15108
15109         final long curRealtime = SystemClock.elapsedRealtime();
15110         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15111         final long curUptime = SystemClock.uptimeMillis();
15112         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15113
15114         for (int i=list.size()-1; i>=0; i--) {
15115             ProcessRecord r = list.get(i).first;
15116             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15117             char schedGroup;
15118             switch (r.setSchedGroup) {
15119                 case ProcessList.SCHED_GROUP_BACKGROUND:
15120                     schedGroup = 'B';
15121                     break;
15122                 case ProcessList.SCHED_GROUP_DEFAULT:
15123                     schedGroup = 'F';
15124                     break;
15125                 case ProcessList.SCHED_GROUP_TOP_APP:
15126                     schedGroup = 'T';
15127                     break;
15128                 default:
15129                     schedGroup = '?';
15130                     break;
15131             }
15132             char foreground;
15133             if (r.foregroundActivities) {
15134                 foreground = 'A';
15135             } else if (r.foregroundServices) {
15136                 foreground = 'S';
15137             } else {
15138                 foreground = ' ';
15139             }
15140             String procState = ProcessList.makeProcStateString(r.curProcState);
15141             pw.print(prefix);
15142             pw.print(r.persistent ? persistentLabel : normalLabel);
15143             pw.print(" #");
15144             int num = (origList.size()-1)-list.get(i).second;
15145             if (num < 10) pw.print(' ');
15146             pw.print(num);
15147             pw.print(": ");
15148             pw.print(oomAdj);
15149             pw.print(' ');
15150             pw.print(schedGroup);
15151             pw.print('/');
15152             pw.print(foreground);
15153             pw.print('/');
15154             pw.print(procState);
15155             pw.print(" trm:");
15156             if (r.trimMemoryLevel < 10) pw.print(' ');
15157             pw.print(r.trimMemoryLevel);
15158             pw.print(' ');
15159             pw.print(r.toShortString());
15160             pw.print(" (");
15161             pw.print(r.adjType);
15162             pw.println(')');
15163             if (r.adjSource != null || r.adjTarget != null) {
15164                 pw.print(prefix);
15165                 pw.print("    ");
15166                 if (r.adjTarget instanceof ComponentName) {
15167                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15168                 } else if (r.adjTarget != null) {
15169                     pw.print(r.adjTarget.toString());
15170                 } else {
15171                     pw.print("{null}");
15172                 }
15173                 pw.print("<=");
15174                 if (r.adjSource instanceof ProcessRecord) {
15175                     pw.print("Proc{");
15176                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15177                     pw.println("}");
15178                 } else if (r.adjSource != null) {
15179                     pw.println(r.adjSource.toString());
15180                 } else {
15181                     pw.println("{null}");
15182                 }
15183             }
15184             if (inclDetails) {
15185                 pw.print(prefix);
15186                 pw.print("    ");
15187                 pw.print("oom: max="); pw.print(r.maxAdj);
15188                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15189                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15190                 pw.print(" cur="); pw.print(r.curAdj);
15191                 pw.print(" set="); pw.println(r.setAdj);
15192                 pw.print(prefix);
15193                 pw.print("    ");
15194                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15195                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15196                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15197                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15198                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15199                 pw.println();
15200                 pw.print(prefix);
15201                 pw.print("    ");
15202                 pw.print("cached="); pw.print(r.cached);
15203                 pw.print(" empty="); pw.print(r.empty);
15204                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15205
15206                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15207                     if (r.lastWakeTime != 0) {
15208                         long wtime;
15209                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15210                         synchronized (stats) {
15211                             wtime = stats.getProcessWakeTime(r.info.uid,
15212                                     r.pid, curRealtime);
15213                         }
15214                         long timeUsed = wtime - r.lastWakeTime;
15215                         pw.print(prefix);
15216                         pw.print("    ");
15217                         pw.print("keep awake over ");
15218                         TimeUtils.formatDuration(realtimeSince, pw);
15219                         pw.print(" used ");
15220                         TimeUtils.formatDuration(timeUsed, pw);
15221                         pw.print(" (");
15222                         pw.print((timeUsed*100)/realtimeSince);
15223                         pw.println("%)");
15224                     }
15225                     if (r.lastCpuTime != 0) {
15226                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15227                         pw.print(prefix);
15228                         pw.print("    ");
15229                         pw.print("run cpu over ");
15230                         TimeUtils.formatDuration(uptimeSince, pw);
15231                         pw.print(" used ");
15232                         TimeUtils.formatDuration(timeUsed, pw);
15233                         pw.print(" (");
15234                         pw.print((timeUsed*100)/uptimeSince);
15235                         pw.println("%)");
15236                     }
15237                 }
15238             }
15239         }
15240         return true;
15241     }
15242
15243     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15244             String[] args) {
15245         ArrayList<ProcessRecord> procs;
15246         synchronized (this) {
15247             if (args != null && args.length > start
15248                     && args[start].charAt(0) != '-') {
15249                 procs = new ArrayList<ProcessRecord>();
15250                 int pid = -1;
15251                 try {
15252                     pid = Integer.parseInt(args[start]);
15253                 } catch (NumberFormatException e) {
15254                 }
15255                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15256                     ProcessRecord proc = mLruProcesses.get(i);
15257                     if (proc.pid == pid) {
15258                         procs.add(proc);
15259                     } else if (allPkgs && proc.pkgList != null
15260                             && proc.pkgList.containsKey(args[start])) {
15261                         procs.add(proc);
15262                     } else if (proc.processName.equals(args[start])) {
15263                         procs.add(proc);
15264                     }
15265                 }
15266                 if (procs.size() <= 0) {
15267                     return null;
15268                 }
15269             } else {
15270                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15271             }
15272         }
15273         return procs;
15274     }
15275
15276     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15277             PrintWriter pw, String[] args) {
15278         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15279         if (procs == null) {
15280             pw.println("No process found for: " + args[0]);
15281             return;
15282         }
15283
15284         long uptime = SystemClock.uptimeMillis();
15285         long realtime = SystemClock.elapsedRealtime();
15286         pw.println("Applications Graphics Acceleration Info:");
15287         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15288
15289         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15290             ProcessRecord r = procs.get(i);
15291             if (r.thread != null) {
15292                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15293                 pw.flush();
15294                 try {
15295                     TransferPipe tp = new TransferPipe();
15296                     try {
15297                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15298                         tp.go(fd);
15299                     } finally {
15300                         tp.kill();
15301                     }
15302                 } catch (IOException e) {
15303                     pw.println("Failure while dumping the app: " + r);
15304                     pw.flush();
15305                 } catch (RemoteException e) {
15306                     pw.println("Got a RemoteException while dumping the app " + r);
15307                     pw.flush();
15308                 }
15309             }
15310         }
15311     }
15312
15313     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15314         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15315         if (procs == null) {
15316             pw.println("No process found for: " + args[0]);
15317             return;
15318         }
15319
15320         pw.println("Applications Database Info:");
15321
15322         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15323             ProcessRecord r = procs.get(i);
15324             if (r.thread != null) {
15325                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15326                 pw.flush();
15327                 try {
15328                     TransferPipe tp = new TransferPipe();
15329                     try {
15330                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15331                         tp.go(fd);
15332                     } finally {
15333                         tp.kill();
15334                     }
15335                 } catch (IOException e) {
15336                     pw.println("Failure while dumping the app: " + r);
15337                     pw.flush();
15338                 } catch (RemoteException e) {
15339                     pw.println("Got a RemoteException while dumping the app " + r);
15340                     pw.flush();
15341                 }
15342             }
15343         }
15344     }
15345
15346     final static class MemItem {
15347         final boolean isProc;
15348         final String label;
15349         final String shortLabel;
15350         final long pss;
15351         final long swapPss;
15352         final int id;
15353         final boolean hasActivities;
15354         ArrayList<MemItem> subitems;
15355
15356         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15357                 boolean _hasActivities) {
15358             isProc = true;
15359             label = _label;
15360             shortLabel = _shortLabel;
15361             pss = _pss;
15362             swapPss = _swapPss;
15363             id = _id;
15364             hasActivities = _hasActivities;
15365         }
15366
15367         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15368             isProc = false;
15369             label = _label;
15370             shortLabel = _shortLabel;
15371             pss = _pss;
15372             swapPss = _swapPss;
15373             id = _id;
15374             hasActivities = false;
15375         }
15376     }
15377
15378     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15379             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15380         if (sort && !isCompact) {
15381             Collections.sort(items, new Comparator<MemItem>() {
15382                 @Override
15383                 public int compare(MemItem lhs, MemItem rhs) {
15384                     if (lhs.pss < rhs.pss) {
15385                         return 1;
15386                     } else if (lhs.pss > rhs.pss) {
15387                         return -1;
15388                     }
15389                     return 0;
15390                 }
15391             });
15392         }
15393
15394         for (int i=0; i<items.size(); i++) {
15395             MemItem mi = items.get(i);
15396             if (!isCompact) {
15397                 if (dumpSwapPss) {
15398                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15399                             mi.label, stringifyKBSize(mi.swapPss));
15400                 } else {
15401                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15402                 }
15403             } else if (mi.isProc) {
15404                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15405                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15406                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15407                 pw.println(mi.hasActivities ? ",a" : ",e");
15408             } else {
15409                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15410                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15411             }
15412             if (mi.subitems != null) {
15413                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15414                         true, isCompact, dumpSwapPss);
15415             }
15416         }
15417     }
15418
15419     // These are in KB.
15420     static final long[] DUMP_MEM_BUCKETS = new long[] {
15421         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15422         120*1024, 160*1024, 200*1024,
15423         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15424         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15425     };
15426
15427     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15428             boolean stackLike) {
15429         int start = label.lastIndexOf('.');
15430         if (start >= 0) start++;
15431         else start = 0;
15432         int end = label.length();
15433         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15434             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15435                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15436                 out.append(bucket);
15437                 out.append(stackLike ? "MB." : "MB ");
15438                 out.append(label, start, end);
15439                 return;
15440             }
15441         }
15442         out.append(memKB/1024);
15443         out.append(stackLike ? "MB." : "MB ");
15444         out.append(label, start, end);
15445     }
15446
15447     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15448             ProcessList.NATIVE_ADJ,
15449             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15450             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15451             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15452             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15453             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15454             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15455     };
15456     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15457             "Native",
15458             "System", "Persistent", "Persistent Service", "Foreground",
15459             "Visible", "Perceptible",
15460             "Heavy Weight", "Backup",
15461             "A Services", "Home",
15462             "Previous", "B Services", "Cached"
15463     };
15464     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15465             "native",
15466             "sys", "pers", "persvc", "fore",
15467             "vis", "percept",
15468             "heavy", "backup",
15469             "servicea", "home",
15470             "prev", "serviceb", "cached"
15471     };
15472
15473     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15474             long realtime, boolean isCheckinRequest, boolean isCompact) {
15475         if (isCompact) {
15476             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15477         }
15478         if (isCheckinRequest || isCompact) {
15479             // short checkin version
15480             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15481         } else {
15482             pw.println("Applications Memory Usage (in Kilobytes):");
15483             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15484         }
15485     }
15486
15487     private static final int KSM_SHARED = 0;
15488     private static final int KSM_SHARING = 1;
15489     private static final int KSM_UNSHARED = 2;
15490     private static final int KSM_VOLATILE = 3;
15491
15492     private final long[] getKsmInfo() {
15493         long[] longOut = new long[4];
15494         final int[] SINGLE_LONG_FORMAT = new int[] {
15495             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15496         };
15497         long[] longTmp = new long[1];
15498         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15499                 SINGLE_LONG_FORMAT, null, longTmp, null);
15500         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15501         longTmp[0] = 0;
15502         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15503                 SINGLE_LONG_FORMAT, null, longTmp, null);
15504         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15505         longTmp[0] = 0;
15506         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15507                 SINGLE_LONG_FORMAT, null, longTmp, null);
15508         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15509         longTmp[0] = 0;
15510         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15511                 SINGLE_LONG_FORMAT, null, longTmp, null);
15512         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15513         return longOut;
15514     }
15515
15516     private static String stringifySize(long size, int order) {
15517         Locale locale = Locale.US;
15518         switch (order) {
15519             case 1:
15520                 return String.format(locale, "%,13d", size);
15521             case 1024:
15522                 return String.format(locale, "%,9dK", size / 1024);
15523             case 1024 * 1024:
15524                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15525             case 1024 * 1024 * 1024:
15526                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15527             default:
15528                 throw new IllegalArgumentException("Invalid size order");
15529         }
15530     }
15531
15532     private static String stringifyKBSize(long size) {
15533         return stringifySize(size * 1024, 1024);
15534     }
15535
15536     // Update this version number in case you change the 'compact' format
15537     private static final int MEMINFO_COMPACT_VERSION = 1;
15538
15539     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15540             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15541         boolean dumpDetails = false;
15542         boolean dumpFullDetails = false;
15543         boolean dumpDalvik = false;
15544         boolean dumpSummaryOnly = false;
15545         boolean dumpUnreachable = false;
15546         boolean oomOnly = false;
15547         boolean isCompact = false;
15548         boolean localOnly = false;
15549         boolean packages = false;
15550         boolean isCheckinRequest = false;
15551         boolean dumpSwapPss = false;
15552
15553         int opti = 0;
15554         while (opti < args.length) {
15555             String opt = args[opti];
15556             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15557                 break;
15558             }
15559             opti++;
15560             if ("-a".equals(opt)) {
15561                 dumpDetails = true;
15562                 dumpFullDetails = true;
15563                 dumpDalvik = true;
15564                 dumpSwapPss = true;
15565             } else if ("-d".equals(opt)) {
15566                 dumpDalvik = true;
15567             } else if ("-c".equals(opt)) {
15568                 isCompact = true;
15569             } else if ("-s".equals(opt)) {
15570                 dumpDetails = true;
15571                 dumpSummaryOnly = true;
15572             } else if ("-S".equals(opt)) {
15573                 dumpSwapPss = true;
15574             } else if ("--unreachable".equals(opt)) {
15575                 dumpUnreachable = true;
15576             } else if ("--oom".equals(opt)) {
15577                 oomOnly = true;
15578             } else if ("--local".equals(opt)) {
15579                 localOnly = true;
15580             } else if ("--package".equals(opt)) {
15581                 packages = true;
15582             } else if ("--checkin".equals(opt)) {
15583                 isCheckinRequest = true;
15584
15585             } else if ("-h".equals(opt)) {
15586                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15587                 pw.println("  -a: include all available information for each process.");
15588                 pw.println("  -d: include dalvik details.");
15589                 pw.println("  -c: dump in a compact machine-parseable representation.");
15590                 pw.println("  -s: dump only summary of application memory usage.");
15591                 pw.println("  -S: dump also SwapPss.");
15592                 pw.println("  --oom: only show processes organized by oom adj.");
15593                 pw.println("  --local: only collect details locally, don't call process.");
15594                 pw.println("  --package: interpret process arg as package, dumping all");
15595                 pw.println("             processes that have loaded that package.");
15596                 pw.println("  --checkin: dump data for a checkin");
15597                 pw.println("If [process] is specified it can be the name or ");
15598                 pw.println("pid of a specific process to dump.");
15599                 return;
15600             } else {
15601                 pw.println("Unknown argument: " + opt + "; use -h for help");
15602             }
15603         }
15604
15605         long uptime = SystemClock.uptimeMillis();
15606         long realtime = SystemClock.elapsedRealtime();
15607         final long[] tmpLong = new long[1];
15608
15609         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15610         if (procs == null) {
15611             // No Java processes.  Maybe they want to print a native process.
15612             if (args != null && args.length > opti
15613                     && args[opti].charAt(0) != '-') {
15614                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15615                         = new ArrayList<ProcessCpuTracker.Stats>();
15616                 updateCpuStatsNow();
15617                 int findPid = -1;
15618                 try {
15619                     findPid = Integer.parseInt(args[opti]);
15620                 } catch (NumberFormatException e) {
15621                 }
15622                 synchronized (mProcessCpuTracker) {
15623                     final int N = mProcessCpuTracker.countStats();
15624                     for (int i=0; i<N; i++) {
15625                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15626                         if (st.pid == findPid || (st.baseName != null
15627                                 && st.baseName.equals(args[opti]))) {
15628                             nativeProcs.add(st);
15629                         }
15630                     }
15631                 }
15632                 if (nativeProcs.size() > 0) {
15633                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15634                             isCompact);
15635                     Debug.MemoryInfo mi = null;
15636                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15637                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15638                         final int pid = r.pid;
15639                         if (!isCheckinRequest && dumpDetails) {
15640                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15641                         }
15642                         if (mi == null) {
15643                             mi = new Debug.MemoryInfo();
15644                         }
15645                         if (dumpDetails || (!brief && !oomOnly)) {
15646                             Debug.getMemoryInfo(pid, mi);
15647                         } else {
15648                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15649                             mi.dalvikPrivateDirty = (int)tmpLong[0];
15650                         }
15651                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15652                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15653                         if (isCheckinRequest) {
15654                             pw.println();
15655                         }
15656                     }
15657                     return;
15658                 }
15659             }
15660             pw.println("No process found for: " + args[opti]);
15661             return;
15662         }
15663
15664         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15665             dumpDetails = true;
15666         }
15667
15668         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15669
15670         String[] innerArgs = new String[args.length-opti];
15671         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15672
15673         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15674         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15675         long nativePss = 0;
15676         long nativeSwapPss = 0;
15677         long dalvikPss = 0;
15678         long dalvikSwapPss = 0;
15679         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15680                 EmptyArray.LONG;
15681         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15682                 EmptyArray.LONG;
15683         long otherPss = 0;
15684         long otherSwapPss = 0;
15685         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15686         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15687
15688         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15689         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15690         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15691                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15692
15693         long totalPss = 0;
15694         long totalSwapPss = 0;
15695         long cachedPss = 0;
15696         long cachedSwapPss = 0;
15697         boolean hasSwapPss = false;
15698
15699         Debug.MemoryInfo mi = null;
15700         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15701             final ProcessRecord r = procs.get(i);
15702             final IApplicationThread thread;
15703             final int pid;
15704             final int oomAdj;
15705             final boolean hasActivities;
15706             synchronized (this) {
15707                 thread = r.thread;
15708                 pid = r.pid;
15709                 oomAdj = r.getSetAdjWithServices();
15710                 hasActivities = r.activities.size() > 0;
15711             }
15712             if (thread != null) {
15713                 if (!isCheckinRequest && dumpDetails) {
15714                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15715                 }
15716                 if (mi == null) {
15717                     mi = new Debug.MemoryInfo();
15718                 }
15719                 if (dumpDetails || (!brief && !oomOnly)) {
15720                     Debug.getMemoryInfo(pid, mi);
15721                     hasSwapPss = mi.hasSwappedOutPss;
15722                 } else {
15723                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15724                     mi.dalvikPrivateDirty = (int)tmpLong[0];
15725                 }
15726                 if (dumpDetails) {
15727                     if (localOnly) {
15728                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15729                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15730                         if (isCheckinRequest) {
15731                             pw.println();
15732                         }
15733                     } else {
15734                         try {
15735                             pw.flush();
15736                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15737                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15738                         } catch (RemoteException e) {
15739                             if (!isCheckinRequest) {
15740                                 pw.println("Got RemoteException!");
15741                                 pw.flush();
15742                             }
15743                         }
15744                     }
15745                 }
15746
15747                 final long myTotalPss = mi.getTotalPss();
15748                 final long myTotalUss = mi.getTotalUss();
15749                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15750
15751                 synchronized (this) {
15752                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15753                         // Record this for posterity if the process has been stable.
15754                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15755                     }
15756                 }
15757
15758                 if (!isCheckinRequest && mi != null) {
15759                     totalPss += myTotalPss;
15760                     totalSwapPss += myTotalSwapPss;
15761                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15762                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15763                             myTotalSwapPss, pid, hasActivities);
15764                     procMems.add(pssItem);
15765                     procMemsMap.put(pid, pssItem);
15766
15767                     nativePss += mi.nativePss;
15768                     nativeSwapPss += mi.nativeSwappedOutPss;
15769                     dalvikPss += mi.dalvikPss;
15770                     dalvikSwapPss += mi.dalvikSwappedOutPss;
15771                     for (int j=0; j<dalvikSubitemPss.length; j++) {
15772                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15773                         dalvikSubitemSwapPss[j] +=
15774                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15775                     }
15776                     otherPss += mi.otherPss;
15777                     otherSwapPss += mi.otherSwappedOutPss;
15778                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15779                         long mem = mi.getOtherPss(j);
15780                         miscPss[j] += mem;
15781                         otherPss -= mem;
15782                         mem = mi.getOtherSwappedOutPss(j);
15783                         miscSwapPss[j] += mem;
15784                         otherSwapPss -= mem;
15785                     }
15786
15787                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15788                         cachedPss += myTotalPss;
15789                         cachedSwapPss += myTotalSwapPss;
15790                     }
15791
15792                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15793                         if (oomIndex == (oomPss.length - 1)
15794                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15795                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15796                             oomPss[oomIndex] += myTotalPss;
15797                             oomSwapPss[oomIndex] += myTotalSwapPss;
15798                             if (oomProcs[oomIndex] == null) {
15799                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
15800                             }
15801                             oomProcs[oomIndex].add(pssItem);
15802                             break;
15803                         }
15804                     }
15805                 }
15806             }
15807         }
15808
15809         long nativeProcTotalPss = 0;
15810
15811         if (!isCheckinRequest && procs.size() > 1 && !packages) {
15812             // If we are showing aggregations, also look for native processes to
15813             // include so that our aggregations are more accurate.
15814             updateCpuStatsNow();
15815             mi = null;
15816             synchronized (mProcessCpuTracker) {
15817                 final int N = mProcessCpuTracker.countStats();
15818                 for (int i=0; i<N; i++) {
15819                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15820                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15821                         if (mi == null) {
15822                             mi = new Debug.MemoryInfo();
15823                         }
15824                         if (!brief && !oomOnly) {
15825                             Debug.getMemoryInfo(st.pid, mi);
15826                         } else {
15827                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15828                             mi.nativePrivateDirty = (int)tmpLong[0];
15829                         }
15830
15831                         final long myTotalPss = mi.getTotalPss();
15832                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15833                         totalPss += myTotalPss;
15834                         nativeProcTotalPss += myTotalPss;
15835
15836                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15837                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15838                         procMems.add(pssItem);
15839
15840                         nativePss += mi.nativePss;
15841                         nativeSwapPss += mi.nativeSwappedOutPss;
15842                         dalvikPss += mi.dalvikPss;
15843                         dalvikSwapPss += mi.dalvikSwappedOutPss;
15844                         for (int j=0; j<dalvikSubitemPss.length; j++) {
15845                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15846                             dalvikSubitemSwapPss[j] +=
15847                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15848                         }
15849                         otherPss += mi.otherPss;
15850                         otherSwapPss += mi.otherSwappedOutPss;
15851                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15852                             long mem = mi.getOtherPss(j);
15853                             miscPss[j] += mem;
15854                             otherPss -= mem;
15855                             mem = mi.getOtherSwappedOutPss(j);
15856                             miscSwapPss[j] += mem;
15857                             otherSwapPss -= mem;
15858                         }
15859                         oomPss[0] += myTotalPss;
15860                         oomSwapPss[0] += myTotalSwapPss;
15861                         if (oomProcs[0] == null) {
15862                             oomProcs[0] = new ArrayList<MemItem>();
15863                         }
15864                         oomProcs[0].add(pssItem);
15865                     }
15866                 }
15867             }
15868
15869             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15870
15871             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15872             final MemItem dalvikItem =
15873                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15874             if (dalvikSubitemPss.length > 0) {
15875                 dalvikItem.subitems = new ArrayList<MemItem>();
15876                 for (int j=0; j<dalvikSubitemPss.length; j++) {
15877                     final String name = Debug.MemoryInfo.getOtherLabel(
15878                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
15879                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15880                                     dalvikSubitemSwapPss[j], j));
15881                 }
15882             }
15883             catMems.add(dalvikItem);
15884             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15885             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15886                 String label = Debug.MemoryInfo.getOtherLabel(j);
15887                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15888             }
15889
15890             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15891             for (int j=0; j<oomPss.length; j++) {
15892                 if (oomPss[j] != 0) {
15893                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15894                             : DUMP_MEM_OOM_LABEL[j];
15895                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15896                             DUMP_MEM_OOM_ADJ[j]);
15897                     item.subitems = oomProcs[j];
15898                     oomMems.add(item);
15899                 }
15900             }
15901
15902             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15903             if (!brief && !oomOnly && !isCompact) {
15904                 pw.println();
15905                 pw.println("Total PSS by process:");
15906                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15907                 pw.println();
15908             }
15909             if (!isCompact) {
15910                 pw.println("Total PSS by OOM adjustment:");
15911             }
15912             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15913             if (!brief && !oomOnly) {
15914                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15915                 if (!isCompact) {
15916                     out.println();
15917                     out.println("Total PSS by category:");
15918                 }
15919                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15920             }
15921             if (!isCompact) {
15922                 pw.println();
15923             }
15924             MemInfoReader memInfo = new MemInfoReader();
15925             memInfo.readMemInfo();
15926             if (nativeProcTotalPss > 0) {
15927                 synchronized (this) {
15928                     final long cachedKb = memInfo.getCachedSizeKb();
15929                     final long freeKb = memInfo.getFreeSizeKb();
15930                     final long zramKb = memInfo.getZramTotalSizeKb();
15931                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15932                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15933                             kernelKb*1024, nativeProcTotalPss*1024);
15934                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15935                             nativeProcTotalPss);
15936                 }
15937             }
15938             if (!brief) {
15939                 if (!isCompact) {
15940                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15941                     pw.print(" (status ");
15942                     switch (mLastMemoryLevel) {
15943                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15944                             pw.println("normal)");
15945                             break;
15946                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15947                             pw.println("moderate)");
15948                             break;
15949                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15950                             pw.println("low)");
15951                             break;
15952                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15953                             pw.println("critical)");
15954                             break;
15955                         default:
15956                             pw.print(mLastMemoryLevel);
15957                             pw.println(")");
15958                             break;
15959                     }
15960                     pw.print(" Free RAM: ");
15961                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15962                             + memInfo.getFreeSizeKb()));
15963                     pw.print(" (");
15964                     pw.print(stringifyKBSize(cachedPss));
15965                     pw.print(" cached pss + ");
15966                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15967                     pw.print(" cached kernel + ");
15968                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15969                     pw.println(" free)");
15970                 } else {
15971                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15972                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15973                             + memInfo.getFreeSizeKb()); pw.print(",");
15974                     pw.println(totalPss - cachedPss);
15975                 }
15976             }
15977             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15978                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15979                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15980             if (!isCompact) {
15981                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15982                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15983                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15984                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15985                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15986             } else {
15987                 pw.print("lostram,"); pw.println(lostRAM);
15988             }
15989             if (!brief) {
15990                 if (memInfo.getZramTotalSizeKb() != 0) {
15991                     if (!isCompact) {
15992                         pw.print("     ZRAM: ");
15993                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15994                                 pw.print(" physical used for ");
15995                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15996                                         - memInfo.getSwapFreeSizeKb()));
15997                                 pw.print(" in swap (");
15998                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15999                                 pw.println(" total swap)");
16000                     } else {
16001                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16002                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16003                                 pw.println(memInfo.getSwapFreeSizeKb());
16004                     }
16005                 }
16006                 final long[] ksm = getKsmInfo();
16007                 if (!isCompact) {
16008                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16009                             || ksm[KSM_VOLATILE] != 0) {
16010                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16011                                 pw.print(" saved from shared ");
16012                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16013                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16014                                 pw.print(" unshared; ");
16015                                 pw.print(stringifyKBSize(
16016                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16017                     }
16018                     pw.print("   Tuning: ");
16019                     pw.print(ActivityManager.staticGetMemoryClass());
16020                     pw.print(" (large ");
16021                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16022                     pw.print("), oom ");
16023                     pw.print(stringifySize(
16024                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16025                     pw.print(", restore limit ");
16026                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16027                     if (ActivityManager.isLowRamDeviceStatic()) {
16028                         pw.print(" (low-ram)");
16029                     }
16030                     if (ActivityManager.isHighEndGfx()) {
16031                         pw.print(" (high-end-gfx)");
16032                     }
16033                     pw.println();
16034                 } else {
16035                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16036                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16037                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16038                     pw.print("tuning,");
16039                     pw.print(ActivityManager.staticGetMemoryClass());
16040                     pw.print(',');
16041                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16042                     pw.print(',');
16043                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16044                     if (ActivityManager.isLowRamDeviceStatic()) {
16045                         pw.print(",low-ram");
16046                     }
16047                     if (ActivityManager.isHighEndGfx()) {
16048                         pw.print(",high-end-gfx");
16049                     }
16050                     pw.println();
16051                 }
16052             }
16053         }
16054     }
16055
16056     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16057             long memtrack, String name) {
16058         sb.append("  ");
16059         sb.append(ProcessList.makeOomAdjString(oomAdj));
16060         sb.append(' ');
16061         sb.append(ProcessList.makeProcStateString(procState));
16062         sb.append(' ');
16063         ProcessList.appendRamKb(sb, pss);
16064         sb.append(": ");
16065         sb.append(name);
16066         if (memtrack > 0) {
16067             sb.append(" (");
16068             sb.append(stringifyKBSize(memtrack));
16069             sb.append(" memtrack)");
16070         }
16071     }
16072
16073     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16074         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16075         sb.append(" (pid ");
16076         sb.append(mi.pid);
16077         sb.append(") ");
16078         sb.append(mi.adjType);
16079         sb.append('\n');
16080         if (mi.adjReason != null) {
16081             sb.append("                      ");
16082             sb.append(mi.adjReason);
16083             sb.append('\n');
16084         }
16085     }
16086
16087     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16088         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16089         for (int i=0, N=memInfos.size(); i<N; i++) {
16090             ProcessMemInfo mi = memInfos.get(i);
16091             infoMap.put(mi.pid, mi);
16092         }
16093         updateCpuStatsNow();
16094         long[] memtrackTmp = new long[1];
16095         synchronized (mProcessCpuTracker) {
16096             final int N = mProcessCpuTracker.countStats();
16097             for (int i=0; i<N; i++) {
16098                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16099                 if (st.vsize > 0) {
16100                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
16101                     if (pss > 0) {
16102                         if (infoMap.indexOfKey(st.pid) < 0) {
16103                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16104                                     ProcessList.NATIVE_ADJ, -1, "native", null);
16105                             mi.pss = pss;
16106                             mi.memtrack = memtrackTmp[0];
16107                             memInfos.add(mi);
16108                         }
16109                     }
16110                 }
16111             }
16112         }
16113
16114         long totalPss = 0;
16115         long totalMemtrack = 0;
16116         for (int i=0, N=memInfos.size(); i<N; i++) {
16117             ProcessMemInfo mi = memInfos.get(i);
16118             if (mi.pss == 0) {
16119                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16120                 mi.memtrack = memtrackTmp[0];
16121             }
16122             totalPss += mi.pss;
16123             totalMemtrack += mi.memtrack;
16124         }
16125         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16126             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16127                 if (lhs.oomAdj != rhs.oomAdj) {
16128                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16129                 }
16130                 if (lhs.pss != rhs.pss) {
16131                     return lhs.pss < rhs.pss ? 1 : -1;
16132                 }
16133                 return 0;
16134             }
16135         });
16136
16137         StringBuilder tag = new StringBuilder(128);
16138         StringBuilder stack = new StringBuilder(128);
16139         tag.append("Low on memory -- ");
16140         appendMemBucket(tag, totalPss, "total", false);
16141         appendMemBucket(stack, totalPss, "total", true);
16142
16143         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16144         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16145         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16146
16147         boolean firstLine = true;
16148         int lastOomAdj = Integer.MIN_VALUE;
16149         long extraNativeRam = 0;
16150         long extraNativeMemtrack = 0;
16151         long cachedPss = 0;
16152         for (int i=0, N=memInfos.size(); i<N; i++) {
16153             ProcessMemInfo mi = memInfos.get(i);
16154
16155             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16156                 cachedPss += mi.pss;
16157             }
16158
16159             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16160                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16161                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16162                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16163                 if (lastOomAdj != mi.oomAdj) {
16164                     lastOomAdj = mi.oomAdj;
16165                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16166                         tag.append(" / ");
16167                     }
16168                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16169                         if (firstLine) {
16170                             stack.append(":");
16171                             firstLine = false;
16172                         }
16173                         stack.append("\n\t at ");
16174                     } else {
16175                         stack.append("$");
16176                     }
16177                 } else {
16178                     tag.append(" ");
16179                     stack.append("$");
16180                 }
16181                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16182                     appendMemBucket(tag, mi.pss, mi.name, false);
16183                 }
16184                 appendMemBucket(stack, mi.pss, mi.name, true);
16185                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16186                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16187                     stack.append("(");
16188                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16189                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16190                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16191                             stack.append(":");
16192                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16193                         }
16194                     }
16195                     stack.append(")");
16196                 }
16197             }
16198
16199             appendMemInfo(fullNativeBuilder, mi);
16200             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16201                 // The short form only has native processes that are >= 512K.
16202                 if (mi.pss >= 512) {
16203                     appendMemInfo(shortNativeBuilder, mi);
16204                 } else {
16205                     extraNativeRam += mi.pss;
16206                     extraNativeMemtrack += mi.memtrack;
16207                 }
16208             } else {
16209                 // Short form has all other details, but if we have collected RAM
16210                 // from smaller native processes let's dump a summary of that.
16211                 if (extraNativeRam > 0) {
16212                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16213                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16214                     shortNativeBuilder.append('\n');
16215                     extraNativeRam = 0;
16216                 }
16217                 appendMemInfo(fullJavaBuilder, mi);
16218             }
16219         }
16220
16221         fullJavaBuilder.append("           ");
16222         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16223         fullJavaBuilder.append(": TOTAL");
16224         if (totalMemtrack > 0) {
16225             fullJavaBuilder.append(" (");
16226             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16227             fullJavaBuilder.append(" memtrack)");
16228         } else {
16229         }
16230         fullJavaBuilder.append("\n");
16231
16232         MemInfoReader memInfo = new MemInfoReader();
16233         memInfo.readMemInfo();
16234         final long[] infos = memInfo.getRawInfo();
16235
16236         StringBuilder memInfoBuilder = new StringBuilder(1024);
16237         Debug.getMemInfo(infos);
16238         memInfoBuilder.append("  MemInfo: ");
16239         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16240         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16241         memInfoBuilder.append(stringifyKBSize(
16242                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16243         memInfoBuilder.append(stringifyKBSize(
16244                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16245         memInfoBuilder.append(stringifyKBSize(
16246                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16247         memInfoBuilder.append("           ");
16248         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16249         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16250         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16251         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16252         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16253             memInfoBuilder.append("  ZRAM: ");
16254             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16255             memInfoBuilder.append(" RAM, ");
16256             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16257             memInfoBuilder.append(" swap total, ");
16258             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16259             memInfoBuilder.append(" swap free\n");
16260         }
16261         final long[] ksm = getKsmInfo();
16262         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16263                 || ksm[KSM_VOLATILE] != 0) {
16264             memInfoBuilder.append("  KSM: ");
16265             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16266             memInfoBuilder.append(" saved from shared ");
16267             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16268             memInfoBuilder.append("\n       ");
16269             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16270             memInfoBuilder.append(" unshared; ");
16271             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16272             memInfoBuilder.append(" volatile\n");
16273         }
16274         memInfoBuilder.append("  Free RAM: ");
16275         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16276                 + memInfo.getFreeSizeKb()));
16277         memInfoBuilder.append("\n");
16278         memInfoBuilder.append("  Used RAM: ");
16279         memInfoBuilder.append(stringifyKBSize(
16280                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16281         memInfoBuilder.append("\n");
16282         memInfoBuilder.append("  Lost RAM: ");
16283         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16284                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16285                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16286         memInfoBuilder.append("\n");
16287         Slog.i(TAG, "Low on memory:");
16288         Slog.i(TAG, shortNativeBuilder.toString());
16289         Slog.i(TAG, fullJavaBuilder.toString());
16290         Slog.i(TAG, memInfoBuilder.toString());
16291
16292         StringBuilder dropBuilder = new StringBuilder(1024);
16293         /*
16294         StringWriter oomSw = new StringWriter();
16295         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16296         StringWriter catSw = new StringWriter();
16297         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16298         String[] emptyArgs = new String[] { };
16299         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16300         oomPw.flush();
16301         String oomString = oomSw.toString();
16302         */
16303         dropBuilder.append("Low on memory:");
16304         dropBuilder.append(stack);
16305         dropBuilder.append('\n');
16306         dropBuilder.append(fullNativeBuilder);
16307         dropBuilder.append(fullJavaBuilder);
16308         dropBuilder.append('\n');
16309         dropBuilder.append(memInfoBuilder);
16310         dropBuilder.append('\n');
16311         /*
16312         dropBuilder.append(oomString);
16313         dropBuilder.append('\n');
16314         */
16315         StringWriter catSw = new StringWriter();
16316         synchronized (ActivityManagerService.this) {
16317             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16318             String[] emptyArgs = new String[] { };
16319             catPw.println();
16320             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16321             catPw.println();
16322             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16323                     false, null).dumpLocked();
16324             catPw.println();
16325             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16326             catPw.flush();
16327         }
16328         dropBuilder.append(catSw.toString());
16329         addErrorToDropBox("lowmem", null, "system_server", null,
16330                 null, tag.toString(), dropBuilder.toString(), null, null);
16331         //Slog.i(TAG, "Sent to dropbox:");
16332         //Slog.i(TAG, dropBuilder.toString());
16333         synchronized (ActivityManagerService.this) {
16334             long now = SystemClock.uptimeMillis();
16335             if (mLastMemUsageReportTime < now) {
16336                 mLastMemUsageReportTime = now;
16337             }
16338         }
16339     }
16340
16341     /**
16342      * Searches array of arguments for the specified string
16343      * @param args array of argument strings
16344      * @param value value to search for
16345      * @return true if the value is contained in the array
16346      */
16347     private static boolean scanArgs(String[] args, String value) {
16348         if (args != null) {
16349             for (String arg : args) {
16350                 if (value.equals(arg)) {
16351                     return true;
16352                 }
16353             }
16354         }
16355         return false;
16356     }
16357
16358     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16359             ContentProviderRecord cpr, boolean always) {
16360         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16361
16362         if (!inLaunching || always) {
16363             synchronized (cpr) {
16364                 cpr.launchingApp = null;
16365                 cpr.notifyAll();
16366             }
16367             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16368             String names[] = cpr.info.authority.split(";");
16369             for (int j = 0; j < names.length; j++) {
16370                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16371             }
16372         }
16373
16374         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16375             ContentProviderConnection conn = cpr.connections.get(i);
16376             if (conn.waiting) {
16377                 // If this connection is waiting for the provider, then we don't
16378                 // need to mess with its process unless we are always removing
16379                 // or for some reason the provider is not currently launching.
16380                 if (inLaunching && !always) {
16381                     continue;
16382                 }
16383             }
16384             ProcessRecord capp = conn.client;
16385             conn.dead = true;
16386             if (conn.stableCount > 0) {
16387                 if (!capp.persistent && capp.thread != null
16388                         && capp.pid != 0
16389                         && capp.pid != MY_PID) {
16390                     capp.kill("depends on provider "
16391                             + cpr.name.flattenToShortString()
16392                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16393                 }
16394             } else if (capp.thread != null && conn.provider.provider != null) {
16395                 try {
16396                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16397                 } catch (RemoteException e) {
16398                 }
16399                 // In the protocol here, we don't expect the client to correctly
16400                 // clean up this connection, we'll just remove it.
16401                 cpr.connections.remove(i);
16402                 if (conn.client.conProviders.remove(conn)) {
16403                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16404                 }
16405             }
16406         }
16407
16408         if (inLaunching && always) {
16409             mLaunchingProviders.remove(cpr);
16410         }
16411         return inLaunching;
16412     }
16413
16414     /**
16415      * Main code for cleaning up a process when it has gone away.  This is
16416      * called both as a result of the process dying, or directly when stopping
16417      * a process when running in single process mode.
16418      *
16419      * @return Returns true if the given process has been restarted, so the
16420      * app that was passed in must remain on the process lists.
16421      */
16422     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16423             boolean restarting, boolean allowRestart, int index) {
16424         if (index >= 0) {
16425             removeLruProcessLocked(app);
16426             ProcessList.remove(app.pid);
16427         }
16428
16429         mProcessesToGc.remove(app);
16430         mPendingPssProcesses.remove(app);
16431
16432         // Dismiss any open dialogs.
16433         if (app.crashDialog != null && !app.forceCrashReport) {
16434             app.crashDialog.dismiss();
16435             app.crashDialog = null;
16436         }
16437         if (app.anrDialog != null) {
16438             app.anrDialog.dismiss();
16439             app.anrDialog = null;
16440         }
16441         if (app.waitDialog != null) {
16442             app.waitDialog.dismiss();
16443             app.waitDialog = null;
16444         }
16445
16446         app.crashing = false;
16447         app.notResponding = false;
16448
16449         app.resetPackageList(mProcessStats);
16450         app.unlinkDeathRecipient();
16451         app.makeInactive(mProcessStats);
16452         app.waitingToKill = null;
16453         app.forcingToForeground = null;
16454         updateProcessForegroundLocked(app, false, false);
16455         app.foregroundActivities = false;
16456         app.hasShownUi = false;
16457         app.treatLikeActivity = false;
16458         app.hasAboveClient = false;
16459         app.hasClientActivities = false;
16460
16461         mServices.killServicesLocked(app, allowRestart);
16462
16463         boolean restart = false;
16464
16465         // Remove published content providers.
16466         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16467             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16468             final boolean always = app.bad || !allowRestart;
16469             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16470             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16471                 // We left the provider in the launching list, need to
16472                 // restart it.
16473                 restart = true;
16474             }
16475
16476             cpr.provider = null;
16477             cpr.proc = null;
16478         }
16479         app.pubProviders.clear();
16480
16481         // Take care of any launching providers waiting for this process.
16482         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16483             restart = true;
16484         }
16485
16486         // Unregister from connected content providers.
16487         if (!app.conProviders.isEmpty()) {
16488             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16489                 ContentProviderConnection conn = app.conProviders.get(i);
16490                 conn.provider.connections.remove(conn);
16491                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16492                         conn.provider.name);
16493             }
16494             app.conProviders.clear();
16495         }
16496
16497         // At this point there may be remaining entries in mLaunchingProviders
16498         // where we were the only one waiting, so they are no longer of use.
16499         // Look for these and clean up if found.
16500         // XXX Commented out for now.  Trying to figure out a way to reproduce
16501         // the actual situation to identify what is actually going on.
16502         if (false) {
16503             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16504                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16505                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16506                     synchronized (cpr) {
16507                         cpr.launchingApp = null;
16508                         cpr.notifyAll();
16509                     }
16510                 }
16511             }
16512         }
16513
16514         skipCurrentReceiverLocked(app);
16515
16516         // Unregister any receivers.
16517         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16518             removeReceiverLocked(app.receivers.valueAt(i));
16519         }
16520         app.receivers.clear();
16521
16522         // If the app is undergoing backup, tell the backup manager about it
16523         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16524             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16525                     + mBackupTarget.appInfo + " died during backup");
16526             try {
16527                 IBackupManager bm = IBackupManager.Stub.asInterface(
16528                         ServiceManager.getService(Context.BACKUP_SERVICE));
16529                 bm.agentDisconnected(app.info.packageName);
16530             } catch (RemoteException e) {
16531                 // can't happen; backup manager is local
16532             }
16533         }
16534
16535         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16536             ProcessChangeItem item = mPendingProcessChanges.get(i);
16537             if (item.pid == app.pid) {
16538                 mPendingProcessChanges.remove(i);
16539                 mAvailProcessChanges.add(item);
16540             }
16541         }
16542         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16543                 null).sendToTarget();
16544
16545         // If the caller is restarting this app, then leave it in its
16546         // current lists and let the caller take care of it.
16547         if (restarting) {
16548             return false;
16549         }
16550
16551         if (!app.persistent || app.isolated) {
16552             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16553                     "Removing non-persistent process during cleanup: " + app);
16554             removeProcessNameLocked(app.processName, app.uid);
16555             if (mHeavyWeightProcess == app) {
16556                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16557                         mHeavyWeightProcess.userId, 0));
16558                 mHeavyWeightProcess = null;
16559             }
16560         } else if (!app.removed) {
16561             // This app is persistent, so we need to keep its record around.
16562             // If it is not already on the pending app list, add it there
16563             // and start a new process for it.
16564             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16565                 mPersistentStartingProcesses.add(app);
16566                 restart = true;
16567             }
16568         }
16569         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16570                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16571         mProcessesOnHold.remove(app);
16572
16573         if (app == mHomeProcess) {
16574             mHomeProcess = null;
16575         }
16576         if (app == mPreviousProcess) {
16577             mPreviousProcess = null;
16578         }
16579
16580         if (restart && !app.isolated) {
16581             // We have components that still need to be running in the
16582             // process, so re-launch it.
16583             if (index < 0) {
16584                 ProcessList.remove(app.pid);
16585             }
16586             addProcessNameLocked(app);
16587             startProcessLocked(app, "restart", app.processName);
16588             return true;
16589         } else if (app.pid > 0 && app.pid != MY_PID) {
16590             // Goodbye!
16591             boolean removed;
16592             synchronized (mPidsSelfLocked) {
16593                 mPidsSelfLocked.remove(app.pid);
16594                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16595             }
16596             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16597             if (app.isolated) {
16598                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16599             }
16600             app.setPid(0);
16601         }
16602         return false;
16603     }
16604
16605     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16606         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16607             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16608             if (cpr.launchingApp == app) {
16609                 return true;
16610             }
16611         }
16612         return false;
16613     }
16614
16615     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16616         // Look through the content providers we are waiting to have launched,
16617         // and if any run in this process then either schedule a restart of
16618         // the process or kill the client waiting for it if this process has
16619         // gone bad.
16620         boolean restart = false;
16621         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16622             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16623             if (cpr.launchingApp == app) {
16624                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16625                     restart = true;
16626                 } else {
16627                     removeDyingProviderLocked(app, cpr, true);
16628                 }
16629             }
16630         }
16631         return restart;
16632     }
16633
16634     // =========================================================
16635     // SERVICES
16636     // =========================================================
16637
16638     @Override
16639     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16640             int flags) {
16641         enforceNotIsolatedCaller("getServices");
16642         synchronized (this) {
16643             return mServices.getRunningServiceInfoLocked(maxNum, flags);
16644         }
16645     }
16646
16647     @Override
16648     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16649         enforceNotIsolatedCaller("getRunningServiceControlPanel");
16650         synchronized (this) {
16651             return mServices.getRunningServiceControlPanelLocked(name);
16652         }
16653     }
16654
16655     @Override
16656     public ComponentName startService(IApplicationThread caller, Intent service,
16657             String resolvedType, String callingPackage, int userId)
16658             throws TransactionTooLargeException {
16659         enforceNotIsolatedCaller("startService");
16660         // Refuse possible leaked file descriptors
16661         if (service != null && service.hasFileDescriptors() == true) {
16662             throw new IllegalArgumentException("File descriptors passed in Intent");
16663         }
16664
16665         if (callingPackage == null) {
16666             throw new IllegalArgumentException("callingPackage cannot be null");
16667         }
16668
16669         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16670                 "startService: " + service + " type=" + resolvedType);
16671         synchronized(this) {
16672             final int callingPid = Binder.getCallingPid();
16673             final int callingUid = Binder.getCallingUid();
16674             final long origId = Binder.clearCallingIdentity();
16675             ComponentName res = mServices.startServiceLocked(caller, service,
16676                     resolvedType, callingPid, callingUid, callingPackage, userId);
16677             Binder.restoreCallingIdentity(origId);
16678             return res;
16679         }
16680     }
16681
16682     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16683             String callingPackage, int userId)
16684             throws TransactionTooLargeException {
16685         synchronized(this) {
16686             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16687                     "startServiceInPackage: " + service + " type=" + resolvedType);
16688             final long origId = Binder.clearCallingIdentity();
16689             ComponentName res = mServices.startServiceLocked(null, service,
16690                     resolvedType, -1, uid, callingPackage, userId);
16691             Binder.restoreCallingIdentity(origId);
16692             return res;
16693         }
16694     }
16695
16696     @Override
16697     public int stopService(IApplicationThread caller, Intent service,
16698             String resolvedType, int userId) {
16699         enforceNotIsolatedCaller("stopService");
16700         // Refuse possible leaked file descriptors
16701         if (service != null && service.hasFileDescriptors() == true) {
16702             throw new IllegalArgumentException("File descriptors passed in Intent");
16703         }
16704
16705         synchronized(this) {
16706             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16707         }
16708     }
16709
16710     @Override
16711     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16712         enforceNotIsolatedCaller("peekService");
16713         // Refuse possible leaked file descriptors
16714         if (service != null && service.hasFileDescriptors() == true) {
16715             throw new IllegalArgumentException("File descriptors passed in Intent");
16716         }
16717
16718         if (callingPackage == null) {
16719             throw new IllegalArgumentException("callingPackage cannot be null");
16720         }
16721
16722         synchronized(this) {
16723             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16724         }
16725     }
16726
16727     @Override
16728     public boolean stopServiceToken(ComponentName className, IBinder token,
16729             int startId) {
16730         synchronized(this) {
16731             return mServices.stopServiceTokenLocked(className, token, startId);
16732         }
16733     }
16734
16735     @Override
16736     public void setServiceForeground(ComponentName className, IBinder token,
16737             int id, Notification notification, int flags) {
16738         synchronized(this) {
16739             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16740         }
16741     }
16742
16743     @Override
16744     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16745             boolean requireFull, String name, String callerPackage) {
16746         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16747                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16748     }
16749
16750     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16751             String className, int flags) {
16752         boolean result = false;
16753         // For apps that don't have pre-defined UIDs, check for permission
16754         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16755             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16756                 if (ActivityManager.checkUidPermission(
16757                         INTERACT_ACROSS_USERS,
16758                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16759                     ComponentName comp = new ComponentName(aInfo.packageName, className);
16760                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
16761                             + " requests FLAG_SINGLE_USER, but app does not hold "
16762                             + INTERACT_ACROSS_USERS;
16763                     Slog.w(TAG, msg);
16764                     throw new SecurityException(msg);
16765                 }
16766                 // Permission passed
16767                 result = true;
16768             }
16769         } else if ("system".equals(componentProcessName)) {
16770             result = true;
16771         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16772             // Phone app and persistent apps are allowed to export singleuser providers.
16773             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16774                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16775         }
16776         if (DEBUG_MU) Slog.v(TAG_MU,
16777                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16778                 + Integer.toHexString(flags) + ") = " + result);
16779         return result;
16780     }
16781
16782     /**
16783      * Checks to see if the caller is in the same app as the singleton
16784      * component, or the component is in a special app. It allows special apps
16785      * to export singleton components but prevents exporting singleton
16786      * components for regular apps.
16787      */
16788     boolean isValidSingletonCall(int callingUid, int componentUid) {
16789         int componentAppId = UserHandle.getAppId(componentUid);
16790         return UserHandle.isSameApp(callingUid, componentUid)
16791                 || componentAppId == Process.SYSTEM_UID
16792                 || componentAppId == Process.PHONE_UID
16793                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16794                         == PackageManager.PERMISSION_GRANTED;
16795     }
16796
16797     public int bindService(IApplicationThread caller, IBinder token, Intent service,
16798             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16799             int userId) throws TransactionTooLargeException {
16800         enforceNotIsolatedCaller("bindService");
16801
16802         // Refuse possible leaked file descriptors
16803         if (service != null && service.hasFileDescriptors() == true) {
16804             throw new IllegalArgumentException("File descriptors passed in Intent");
16805         }
16806
16807         if (callingPackage == null) {
16808             throw new IllegalArgumentException("callingPackage cannot be null");
16809         }
16810
16811         synchronized(this) {
16812             return mServices.bindServiceLocked(caller, token, service,
16813                     resolvedType, connection, flags, callingPackage, userId);
16814         }
16815     }
16816
16817     public boolean unbindService(IServiceConnection connection) {
16818         synchronized (this) {
16819             return mServices.unbindServiceLocked(connection);
16820         }
16821     }
16822
16823     public void publishService(IBinder token, Intent intent, IBinder service) {
16824         // Refuse possible leaked file descriptors
16825         if (intent != null && intent.hasFileDescriptors() == true) {
16826             throw new IllegalArgumentException("File descriptors passed in Intent");
16827         }
16828
16829         synchronized(this) {
16830             if (!(token instanceof ServiceRecord)) {
16831                 throw new IllegalArgumentException("Invalid service token");
16832             }
16833             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16834         }
16835     }
16836
16837     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16838         // Refuse possible leaked file descriptors
16839         if (intent != null && intent.hasFileDescriptors() == true) {
16840             throw new IllegalArgumentException("File descriptors passed in Intent");
16841         }
16842
16843         synchronized(this) {
16844             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16845         }
16846     }
16847
16848     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16849         synchronized(this) {
16850             if (!(token instanceof ServiceRecord)) {
16851                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16852                 throw new IllegalArgumentException("Invalid service token");
16853             }
16854             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16855         }
16856     }
16857
16858     // =========================================================
16859     // BACKUP AND RESTORE
16860     // =========================================================
16861
16862     // Cause the target app to be launched if necessary and its backup agent
16863     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16864     // activity manager to announce its creation.
16865     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16866         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16867                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16868         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16869
16870         synchronized(this) {
16871             // !!! TODO: currently no check here that we're already bound
16872             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16873             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16874             synchronized (stats) {
16875                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16876             }
16877
16878             // Backup agent is now in use, its package can't be stopped.
16879             try {
16880                 AppGlobals.getPackageManager().setPackageStoppedState(
16881                         app.packageName, false, UserHandle.getUserId(app.uid));
16882             } catch (RemoteException e) {
16883             } catch (IllegalArgumentException e) {
16884                 Slog.w(TAG, "Failed trying to unstop package "
16885                         + app.packageName + ": " + e);
16886             }
16887
16888             BackupRecord r = new BackupRecord(ss, app, backupMode);
16889             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16890                     ? new ComponentName(app.packageName, app.backupAgentName)
16891                     : new ComponentName("android", "FullBackupAgent");
16892             // startProcessLocked() returns existing proc's record if it's already running
16893             ProcessRecord proc = startProcessLocked(app.processName, app,
16894                     false, 0, "backup", hostingName, false, false, false);
16895             if (proc == null) {
16896                 Slog.e(TAG, "Unable to start backup agent process " + r);
16897                 return false;
16898             }
16899
16900             // If the app is a regular app (uid >= 10000) and not the system server or phone
16901             // process, etc, then mark it as being in full backup so that certain calls to the
16902             // process can be blocked. This is not reset to false anywhere because we kill the
16903             // process after the full backup is done and the ProcessRecord will vaporize anyway.
16904             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16905                 proc.inFullBackup = true;
16906             }
16907             r.app = proc;
16908             mBackupTarget = r;
16909             mBackupAppName = app.packageName;
16910
16911             // Try not to kill the process during backup
16912             updateOomAdjLocked(proc);
16913
16914             // If the process is already attached, schedule the creation of the backup agent now.
16915             // If it is not yet live, this will be done when it attaches to the framework.
16916             if (proc.thread != null) {
16917                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16918                 try {
16919                     proc.thread.scheduleCreateBackupAgent(app,
16920                             compatibilityInfoForPackageLocked(app), backupMode);
16921                 } catch (RemoteException e) {
16922                     // Will time out on the backup manager side
16923                 }
16924             } else {
16925                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16926             }
16927             // Invariants: at this point, the target app process exists and the application
16928             // is either already running or in the process of coming up.  mBackupTarget and
16929             // mBackupAppName describe the app, so that when it binds back to the AM we
16930             // know that it's scheduled for a backup-agent operation.
16931         }
16932
16933         return true;
16934     }
16935
16936     @Override
16937     public void clearPendingBackup() {
16938         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16939         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16940
16941         synchronized (this) {
16942             mBackupTarget = null;
16943             mBackupAppName = null;
16944         }
16945     }
16946
16947     // A backup agent has just come up
16948     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16949         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16950                 + " = " + agent);
16951
16952         synchronized(this) {
16953             if (!agentPackageName.equals(mBackupAppName)) {
16954                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16955                 return;
16956             }
16957         }
16958
16959         long oldIdent = Binder.clearCallingIdentity();
16960         try {
16961             IBackupManager bm = IBackupManager.Stub.asInterface(
16962                     ServiceManager.getService(Context.BACKUP_SERVICE));
16963             bm.agentConnected(agentPackageName, agent);
16964         } catch (RemoteException e) {
16965             // can't happen; the backup manager service is local
16966         } catch (Exception e) {
16967             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16968             e.printStackTrace();
16969         } finally {
16970             Binder.restoreCallingIdentity(oldIdent);
16971         }
16972     }
16973
16974     // done with this agent
16975     public void unbindBackupAgent(ApplicationInfo appInfo) {
16976         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16977         if (appInfo == null) {
16978             Slog.w(TAG, "unbind backup agent for null app");
16979             return;
16980         }
16981
16982         synchronized(this) {
16983             try {
16984                 if (mBackupAppName == null) {
16985                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16986                     return;
16987                 }
16988
16989                 if (!mBackupAppName.equals(appInfo.packageName)) {
16990                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16991                     return;
16992                 }
16993
16994                 // Not backing this app up any more; reset its OOM adjustment
16995                 final ProcessRecord proc = mBackupTarget.app;
16996                 updateOomAdjLocked(proc);
16997
16998                 // If the app crashed during backup, 'thread' will be null here
16999                 if (proc.thread != null) {
17000                     try {
17001                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17002                                 compatibilityInfoForPackageLocked(appInfo));
17003                     } catch (Exception e) {
17004                         Slog.e(TAG, "Exception when unbinding backup agent:");
17005                         e.printStackTrace();
17006                     }
17007                 }
17008             } finally {
17009                 mBackupTarget = null;
17010                 mBackupAppName = null;
17011             }
17012         }
17013     }
17014     // =========================================================
17015     // BROADCASTS
17016     // =========================================================
17017
17018     boolean isPendingBroadcastProcessLocked(int pid) {
17019         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17020                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17021     }
17022
17023     void skipPendingBroadcastLocked(int pid) {
17024             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17025             for (BroadcastQueue queue : mBroadcastQueues) {
17026                 queue.skipPendingBroadcastLocked(pid);
17027             }
17028     }
17029
17030     // The app just attached; send any pending broadcasts that it should receive
17031     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17032         boolean didSomething = false;
17033         for (BroadcastQueue queue : mBroadcastQueues) {
17034             didSomething |= queue.sendPendingBroadcastsLocked(app);
17035         }
17036         return didSomething;
17037     }
17038
17039     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17040             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17041         enforceNotIsolatedCaller("registerReceiver");
17042         ArrayList<Intent> stickyIntents = null;
17043         ProcessRecord callerApp = null;
17044         int callingUid;
17045         int callingPid;
17046         synchronized(this) {
17047             if (caller != null) {
17048                 callerApp = getRecordForAppLocked(caller);
17049                 if (callerApp == null) {
17050                     throw new SecurityException(
17051                             "Unable to find app for caller " + caller
17052                             + " (pid=" + Binder.getCallingPid()
17053                             + ") when registering receiver " + receiver);
17054                 }
17055                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17056                         !callerApp.pkgList.containsKey(callerPackage) &&
17057                         !"android".equals(callerPackage)) {
17058                     throw new SecurityException("Given caller package " + callerPackage
17059                             + " is not running in process " + callerApp);
17060                 }
17061                 callingUid = callerApp.info.uid;
17062                 callingPid = callerApp.pid;
17063             } else {
17064                 callerPackage = null;
17065                 callingUid = Binder.getCallingUid();
17066                 callingPid = Binder.getCallingPid();
17067             }
17068
17069             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17070                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17071
17072             Iterator<String> actions = filter.actionsIterator();
17073             if (actions == null) {
17074                 ArrayList<String> noAction = new ArrayList<String>(1);
17075                 noAction.add(null);
17076                 actions = noAction.iterator();
17077             }
17078
17079             // Collect stickies of users
17080             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17081             while (actions.hasNext()) {
17082                 String action = actions.next();
17083                 for (int id : userIds) {
17084                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17085                     if (stickies != null) {
17086                         ArrayList<Intent> intents = stickies.get(action);
17087                         if (intents != null) {
17088                             if (stickyIntents == null) {
17089                                 stickyIntents = new ArrayList<Intent>();
17090                             }
17091                             stickyIntents.addAll(intents);
17092                         }
17093                     }
17094                 }
17095             }
17096         }
17097
17098         ArrayList<Intent> allSticky = null;
17099         if (stickyIntents != null) {
17100             final ContentResolver resolver = mContext.getContentResolver();
17101             // Look for any matching sticky broadcasts...
17102             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17103                 Intent intent = stickyIntents.get(i);
17104                 // If intent has scheme "content", it will need to acccess
17105                 // provider that needs to lock mProviderMap in ActivityThread
17106                 // and also it may need to wait application response, so we
17107                 // cannot lock ActivityManagerService here.
17108                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17109                     if (allSticky == null) {
17110                         allSticky = new ArrayList<Intent>();
17111                     }
17112                     allSticky.add(intent);
17113                 }
17114             }
17115         }
17116
17117         // The first sticky in the list is returned directly back to the client.
17118         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17119         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17120         if (receiver == null) {
17121             return sticky;
17122         }
17123
17124         synchronized (this) {
17125             if (callerApp != null && (callerApp.thread == null
17126                     || callerApp.thread.asBinder() != caller.asBinder())) {
17127                 // Original caller already died
17128                 return null;
17129             }
17130             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17131             if (rl == null) {
17132                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17133                         userId, receiver);
17134                 if (rl.app != null) {
17135                     rl.app.receivers.add(rl);
17136                 } else {
17137                     try {
17138                         receiver.asBinder().linkToDeath(rl, 0);
17139                     } catch (RemoteException e) {
17140                         return sticky;
17141                     }
17142                     rl.linkedToDeath = true;
17143                 }
17144                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17145             } else if (rl.uid != callingUid) {
17146                 throw new IllegalArgumentException(
17147                         "Receiver requested to register for uid " + callingUid
17148                         + " was previously registered for uid " + rl.uid);
17149             } else if (rl.pid != callingPid) {
17150                 throw new IllegalArgumentException(
17151                         "Receiver requested to register for pid " + callingPid
17152                         + " was previously registered for pid " + rl.pid);
17153             } else if (rl.userId != userId) {
17154                 throw new IllegalArgumentException(
17155                         "Receiver requested to register for user " + userId
17156                         + " was previously registered for user " + rl.userId);
17157             }
17158             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17159                     permission, callingUid, userId);
17160             rl.add(bf);
17161             if (!bf.debugCheck()) {
17162                 Slog.w(TAG, "==> For Dynamic broadcast");
17163             }
17164             mReceiverResolver.addFilter(bf);
17165
17166             // Enqueue broadcasts for all existing stickies that match
17167             // this filter.
17168             if (allSticky != null) {
17169                 ArrayList receivers = new ArrayList();
17170                 receivers.add(bf);
17171
17172                 final int stickyCount = allSticky.size();
17173                 for (int i = 0; i < stickyCount; i++) {
17174                     Intent intent = allSticky.get(i);
17175                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17176                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17177                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17178                             null, 0, null, null, false, true, true, -1);
17179                     queue.enqueueParallelBroadcastLocked(r);
17180                     queue.scheduleBroadcastsLocked();
17181                 }
17182             }
17183
17184             return sticky;
17185         }
17186     }
17187
17188     public void unregisterReceiver(IIntentReceiver receiver) {
17189         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17190
17191         final long origId = Binder.clearCallingIdentity();
17192         try {
17193             boolean doTrim = false;
17194
17195             synchronized(this) {
17196                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17197                 if (rl != null) {
17198                     final BroadcastRecord r = rl.curBroadcast;
17199                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17200                         final boolean doNext = r.queue.finishReceiverLocked(
17201                                 r, r.resultCode, r.resultData, r.resultExtras,
17202                                 r.resultAbort, false);
17203                         if (doNext) {
17204                             doTrim = true;
17205                             r.queue.processNextBroadcast(false);
17206                         }
17207                     }
17208
17209                     if (rl.app != null) {
17210                         rl.app.receivers.remove(rl);
17211                     }
17212                     removeReceiverLocked(rl);
17213                     if (rl.linkedToDeath) {
17214                         rl.linkedToDeath = false;
17215                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17216                     }
17217                 }
17218             }
17219
17220             // If we actually concluded any broadcasts, we might now be able
17221             // to trim the recipients' apps from our working set
17222             if (doTrim) {
17223                 trimApplications();
17224                 return;
17225             }
17226
17227         } finally {
17228             Binder.restoreCallingIdentity(origId);
17229         }
17230     }
17231
17232     void removeReceiverLocked(ReceiverList rl) {
17233         mRegisteredReceivers.remove(rl.receiver.asBinder());
17234         for (int i = rl.size() - 1; i >= 0; i--) {
17235             mReceiverResolver.removeFilter(rl.get(i));
17236         }
17237     }
17238
17239     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17240         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17241             ProcessRecord r = mLruProcesses.get(i);
17242             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17243                 try {
17244                     r.thread.dispatchPackageBroadcast(cmd, packages);
17245                 } catch (RemoteException ex) {
17246                 }
17247             }
17248         }
17249     }
17250
17251     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17252             int callingUid, int[] users) {
17253         // TODO: come back and remove this assumption to triage all broadcasts
17254         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17255
17256         List<ResolveInfo> receivers = null;
17257         try {
17258             HashSet<ComponentName> singleUserReceivers = null;
17259             boolean scannedFirstReceivers = false;
17260             for (int user : users) {
17261                 // Skip users that have Shell restrictions, with exception of always permitted
17262                 // Shell broadcasts
17263                 if (callingUid == Process.SHELL_UID
17264                         && mUserController.hasUserRestriction(
17265                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17266                         && !isPermittedShellBroadcast(intent)) {
17267                     continue;
17268                 }
17269                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17270                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17271                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17272                     // If this is not the system user, we need to check for
17273                     // any receivers that should be filtered out.
17274                     for (int i=0; i<newReceivers.size(); i++) {
17275                         ResolveInfo ri = newReceivers.get(i);
17276                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17277                             newReceivers.remove(i);
17278                             i--;
17279                         }
17280                     }
17281                 }
17282                 if (newReceivers != null && newReceivers.size() == 0) {
17283                     newReceivers = null;
17284                 }
17285                 if (receivers == null) {
17286                     receivers = newReceivers;
17287                 } else if (newReceivers != null) {
17288                     // We need to concatenate the additional receivers
17289                     // found with what we have do far.  This would be easy,
17290                     // but we also need to de-dup any receivers that are
17291                     // singleUser.
17292                     if (!scannedFirstReceivers) {
17293                         // Collect any single user receivers we had already retrieved.
17294                         scannedFirstReceivers = true;
17295                         for (int i=0; i<receivers.size(); i++) {
17296                             ResolveInfo ri = receivers.get(i);
17297                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17298                                 ComponentName cn = new ComponentName(
17299                                         ri.activityInfo.packageName, ri.activityInfo.name);
17300                                 if (singleUserReceivers == null) {
17301                                     singleUserReceivers = new HashSet<ComponentName>();
17302                                 }
17303                                 singleUserReceivers.add(cn);
17304                             }
17305                         }
17306                     }
17307                     // Add the new results to the existing results, tracking
17308                     // and de-dupping single user receivers.
17309                     for (int i=0; i<newReceivers.size(); i++) {
17310                         ResolveInfo ri = newReceivers.get(i);
17311                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17312                             ComponentName cn = new ComponentName(
17313                                     ri.activityInfo.packageName, ri.activityInfo.name);
17314                             if (singleUserReceivers == null) {
17315                                 singleUserReceivers = new HashSet<ComponentName>();
17316                             }
17317                             if (!singleUserReceivers.contains(cn)) {
17318                                 singleUserReceivers.add(cn);
17319                                 receivers.add(ri);
17320                             }
17321                         } else {
17322                             receivers.add(ri);
17323                         }
17324                     }
17325                 }
17326             }
17327         } catch (RemoteException ex) {
17328             // pm is in same process, this will never happen.
17329         }
17330         return receivers;
17331     }
17332
17333     private boolean isPermittedShellBroadcast(Intent intent) {
17334         // remote bugreport should always be allowed to be taken
17335         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17336     }
17337
17338     final int broadcastIntentLocked(ProcessRecord callerApp,
17339             String callerPackage, Intent intent, String resolvedType,
17340             IIntentReceiver resultTo, int resultCode, String resultData,
17341             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17342             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17343         intent = new Intent(intent);
17344
17345         // By default broadcasts do not go to stopped apps.
17346         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17347
17348         // If we have not finished booting, don't allow this to launch new processes.
17349         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17350             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17351         }
17352
17353         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17354                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17355                 + " ordered=" + ordered + " userid=" + userId);
17356         if ((resultTo != null) && !ordered) {
17357             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17358         }
17359
17360         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17361                 ALLOW_NON_FULL, "broadcast", callerPackage);
17362
17363         // Make sure that the user who is receiving this broadcast is running.
17364         // If not, we will just skip it. Make an exception for shutdown broadcasts
17365         // and upgrade steps.
17366
17367         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17368             if ((callingUid != Process.SYSTEM_UID
17369                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17370                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17371                 Slog.w(TAG, "Skipping broadcast of " + intent
17372                         + ": user " + userId + " is stopped");
17373                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17374             }
17375         }
17376
17377         BroadcastOptions brOptions = null;
17378         if (bOptions != null) {
17379             brOptions = new BroadcastOptions(bOptions);
17380             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17381                 // See if the caller is allowed to do this.  Note we are checking against
17382                 // the actual real caller (not whoever provided the operation as say a
17383                 // PendingIntent), because that who is actually supplied the arguments.
17384                 if (checkComponentPermission(
17385                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17386                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17387                         != PackageManager.PERMISSION_GRANTED) {
17388                     String msg = "Permission Denial: " + intent.getAction()
17389                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17390                             + ", uid=" + callingUid + ")"
17391                             + " requires "
17392                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17393                     Slog.w(TAG, msg);
17394                     throw new SecurityException(msg);
17395                 }
17396             }
17397         }
17398
17399         // Verify that protected broadcasts are only being sent by system code,
17400         // and that system code is only sending protected broadcasts.
17401         final String action = intent.getAction();
17402         final boolean isProtectedBroadcast;
17403         try {
17404             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17405         } catch (RemoteException e) {
17406             Slog.w(TAG, "Remote exception", e);
17407             return ActivityManager.BROADCAST_SUCCESS;
17408         }
17409
17410         final boolean isCallerSystem;
17411         switch (UserHandle.getAppId(callingUid)) {
17412             case Process.ROOT_UID:
17413             case Process.SYSTEM_UID:
17414             case Process.PHONE_UID:
17415             case Process.BLUETOOTH_UID:
17416             case Process.NFC_UID:
17417                 isCallerSystem = true;
17418                 break;
17419             default:
17420                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17421                 break;
17422         }
17423
17424         if (isCallerSystem) {
17425             if (isProtectedBroadcast
17426                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17427                     || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17428                     || Intent.ACTION_MEDIA_BUTTON.equals(action)
17429                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17430                     || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17431                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17432                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17433                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17434                     || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17435                     || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17436                 // Broadcast is either protected, or it's a public action that
17437                 // we've relaxed, so it's fine for system internals to send.
17438             } else {
17439                 // The vast majority of broadcasts sent from system internals
17440                 // should be protected to avoid security holes, so yell loudly
17441                 // to ensure we examine these cases.
17442                 if (callerApp != null) {
17443                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17444                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17445                             new Throwable());
17446                 } else {
17447                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17448                             + " from system uid " + UserHandle.formatUid(callingUid)
17449                             + " pkg " + callerPackage,
17450                             new Throwable());
17451                 }
17452             }
17453
17454         } else {
17455             if (isProtectedBroadcast) {
17456                 String msg = "Permission Denial: not allowed to send broadcast "
17457                         + action + " from pid="
17458                         + callingPid + ", uid=" + callingUid;
17459                 Slog.w(TAG, msg);
17460                 throw new SecurityException(msg);
17461
17462             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17463                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17464                 // Special case for compatibility: we don't want apps to send this,
17465                 // but historically it has not been protected and apps may be using it
17466                 // to poke their own app widget.  So, instead of making it protected,
17467                 // just limit it to the caller.
17468                 if (callerPackage == null) {
17469                     String msg = "Permission Denial: not allowed to send broadcast "
17470                             + action + " from unknown caller.";
17471                     Slog.w(TAG, msg);
17472                     throw new SecurityException(msg);
17473                 } else if (intent.getComponent() != null) {
17474                     // They are good enough to send to an explicit component...  verify
17475                     // it is being sent to the calling app.
17476                     if (!intent.getComponent().getPackageName().equals(
17477                             callerPackage)) {
17478                         String msg = "Permission Denial: not allowed to send broadcast "
17479                                 + action + " to "
17480                                 + intent.getComponent().getPackageName() + " from "
17481                                 + callerPackage;
17482                         Slog.w(TAG, msg);
17483                         throw new SecurityException(msg);
17484                     }
17485                 } else {
17486                     // Limit broadcast to their own package.
17487                     intent.setPackage(callerPackage);
17488                 }
17489             }
17490         }
17491
17492         if (action != null) {
17493             switch (action) {
17494                 case Intent.ACTION_UID_REMOVED:
17495                 case Intent.ACTION_PACKAGE_REMOVED:
17496                 case Intent.ACTION_PACKAGE_CHANGED:
17497                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17498                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17499                 case Intent.ACTION_PACKAGES_SUSPENDED:
17500                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17501                     // Handle special intents: if this broadcast is from the package
17502                     // manager about a package being removed, we need to remove all of
17503                     // its activities from the history stack.
17504                     if (checkComponentPermission(
17505                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17506                             callingPid, callingUid, -1, true)
17507                             != PackageManager.PERMISSION_GRANTED) {
17508                         String msg = "Permission Denial: " + intent.getAction()
17509                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17510                                 + ", uid=" + callingUid + ")"
17511                                 + " requires "
17512                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17513                         Slog.w(TAG, msg);
17514                         throw new SecurityException(msg);
17515                     }
17516                     switch (action) {
17517                         case Intent.ACTION_UID_REMOVED:
17518                             final Bundle intentExtras = intent.getExtras();
17519                             final int uid = intentExtras != null
17520                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17521                             if (uid >= 0) {
17522                                 mBatteryStatsService.removeUid(uid);
17523                                 mAppOpsService.uidRemoved(uid);
17524                             }
17525                             break;
17526                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17527                             // If resources are unavailable just force stop all those packages
17528                             // and flush the attribute cache as well.
17529                             String list[] =
17530                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17531                             if (list != null && list.length > 0) {
17532                                 for (int i = 0; i < list.length; i++) {
17533                                     forceStopPackageLocked(list[i], -1, false, true, true,
17534                                             false, false, userId, "storage unmount");
17535                                 }
17536                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17537                                 sendPackageBroadcastLocked(
17538                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17539                                         userId);
17540                             }
17541                             break;
17542                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17543                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17544                             break;
17545                         case Intent.ACTION_PACKAGE_REMOVED:
17546                         case Intent.ACTION_PACKAGE_CHANGED:
17547                             Uri data = intent.getData();
17548                             String ssp;
17549                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17550                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17551                                 final boolean replacing =
17552                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17553                                 final boolean killProcess =
17554                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17555                                 final boolean fullUninstall = removed && !replacing;
17556                                 if (removed) {
17557                                     if (killProcess) {
17558                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
17559                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17560                                                 false, true, true, false, fullUninstall, userId,
17561                                                 removed ? "pkg removed" : "pkg changed");
17562                                     }
17563                                     final int cmd = killProcess
17564                                             ? IApplicationThread.PACKAGE_REMOVED
17565                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17566                                     sendPackageBroadcastLocked(cmd,
17567                                             new String[] {ssp}, userId);
17568                                     if (fullUninstall) {
17569                                         mAppOpsService.packageRemoved(
17570                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17571
17572                                         // Remove all permissions granted from/to this package
17573                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
17574
17575                                         removeTasksByPackageNameLocked(ssp, userId);
17576                                         mBatteryStatsService.notePackageUninstalled(ssp);
17577                                     }
17578                                 } else {
17579                                     if (killProcess) {
17580                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
17581                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17582                                                 userId, ProcessList.INVALID_ADJ,
17583                                                 false, true, true, false, "change " + ssp);
17584                                     }
17585                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17586                                             intent.getStringArrayExtra(
17587                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17588                                 }
17589                             }
17590                             break;
17591                         case Intent.ACTION_PACKAGES_SUSPENDED:
17592                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
17593                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17594                                     intent.getAction());
17595                             final String[] packageNames = intent.getStringArrayExtra(
17596                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
17597                             final int userHandle = intent.getIntExtra(
17598                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17599
17600                             synchronized(ActivityManagerService.this) {
17601                                 mRecentTasks.onPackagesSuspendedChanged(
17602                                         packageNames, suspended, userHandle);
17603                             }
17604                             break;
17605                     }
17606                     break;
17607                 case Intent.ACTION_PACKAGE_REPLACED:
17608                 {
17609                     final Uri data = intent.getData();
17610                     final String ssp;
17611                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17612                         final ApplicationInfo aInfo =
17613                                 getPackageManagerInternalLocked().getApplicationInfo(
17614                                         ssp,
17615                                         userId);
17616                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17617                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17618                                 new String[] {ssp}, userId);
17619                     }
17620                     break;
17621                 }
17622                 case Intent.ACTION_PACKAGE_ADDED:
17623                 {
17624                     // Special case for adding a package: by default turn on compatibility mode.
17625                     Uri data = intent.getData();
17626                     String ssp;
17627                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17628                         final boolean replacing =
17629                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17630                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17631
17632                         try {
17633                             ApplicationInfo ai = AppGlobals.getPackageManager().
17634                                     getApplicationInfo(ssp, 0, 0);
17635                             mBatteryStatsService.notePackageInstalled(ssp,
17636                                     ai != null ? ai.versionCode : 0);
17637                         } catch (RemoteException e) {
17638                         }
17639                     }
17640                     break;
17641                 }
17642                 case Intent.ACTION_TIMEZONE_CHANGED:
17643                     // If this is the time zone changed action, queue up a message that will reset
17644                     // the timezone of all currently running processes. This message will get
17645                     // queued up before the broadcast happens.
17646                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17647                     break;
17648                 case Intent.ACTION_TIME_CHANGED:
17649                     // If the user set the time, let all running processes know.
17650                     final int is24Hour =
17651                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17652                                     : 0;
17653                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17654                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17655                     synchronized (stats) {
17656                         stats.noteCurrentTimeChangedLocked();
17657                     }
17658                     break;
17659                 case Intent.ACTION_CLEAR_DNS_CACHE:
17660                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17661                     break;
17662                 case Proxy.PROXY_CHANGE_ACTION:
17663                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17664                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17665                     break;
17666                 case android.hardware.Camera.ACTION_NEW_PICTURE:
17667                 case android.hardware.Camera.ACTION_NEW_VIDEO:
17668                     // These broadcasts are no longer allowed by the system, since they can
17669                     // cause significant thrashing at a crictical point (using the camera).
17670                     // Apps should use JobScehduler to monitor for media provider changes.
17671                     Slog.w(TAG, action + " no longer allowed; dropping from "
17672                             + UserHandle.formatUid(callingUid));
17673                     // Lie; we don't want to crash the app.
17674                     return ActivityManager.BROADCAST_SUCCESS;
17675             }
17676         }
17677
17678         // Add to the sticky list if requested.
17679         if (sticky) {
17680             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17681                     callingPid, callingUid)
17682                     != PackageManager.PERMISSION_GRANTED) {
17683                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17684                         + callingPid + ", uid=" + callingUid
17685                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17686                 Slog.w(TAG, msg);
17687                 throw new SecurityException(msg);
17688             }
17689             if (requiredPermissions != null && requiredPermissions.length > 0) {
17690                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17691                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
17692                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17693             }
17694             if (intent.getComponent() != null) {
17695                 throw new SecurityException(
17696                         "Sticky broadcasts can't target a specific component");
17697             }
17698             // We use userId directly here, since the "all" target is maintained
17699             // as a separate set of sticky broadcasts.
17700             if (userId != UserHandle.USER_ALL) {
17701                 // But first, if this is not a broadcast to all users, then
17702                 // make sure it doesn't conflict with an existing broadcast to
17703                 // all users.
17704                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17705                         UserHandle.USER_ALL);
17706                 if (stickies != null) {
17707                     ArrayList<Intent> list = stickies.get(intent.getAction());
17708                     if (list != null) {
17709                         int N = list.size();
17710                         int i;
17711                         for (i=0; i<N; i++) {
17712                             if (intent.filterEquals(list.get(i))) {
17713                                 throw new IllegalArgumentException(
17714                                         "Sticky broadcast " + intent + " for user "
17715                                         + userId + " conflicts with existing global broadcast");
17716                             }
17717                         }
17718                     }
17719                 }
17720             }
17721             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17722             if (stickies == null) {
17723                 stickies = new ArrayMap<>();
17724                 mStickyBroadcasts.put(userId, stickies);
17725             }
17726             ArrayList<Intent> list = stickies.get(intent.getAction());
17727             if (list == null) {
17728                 list = new ArrayList<>();
17729                 stickies.put(intent.getAction(), list);
17730             }
17731             final int stickiesCount = list.size();
17732             int i;
17733             for (i = 0; i < stickiesCount; i++) {
17734                 if (intent.filterEquals(list.get(i))) {
17735                     // This sticky already exists, replace it.
17736                     list.set(i, new Intent(intent));
17737                     break;
17738                 }
17739             }
17740             if (i >= stickiesCount) {
17741                 list.add(new Intent(intent));
17742             }
17743         }
17744
17745         int[] users;
17746         if (userId == UserHandle.USER_ALL) {
17747             // Caller wants broadcast to go to all started users.
17748             users = mUserController.getStartedUserArrayLocked();
17749         } else {
17750             // Caller wants broadcast to go to one specific user.
17751             users = new int[] {userId};
17752         }
17753
17754         // Figure out who all will receive this broadcast.
17755         List receivers = null;
17756         List<BroadcastFilter> registeredReceivers = null;
17757         // Need to resolve the intent to interested receivers...
17758         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17759                  == 0) {
17760             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17761         }
17762         if (intent.getComponent() == null) {
17763             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17764                 // Query one target user at a time, excluding shell-restricted users
17765                 for (int i = 0; i < users.length; i++) {
17766                     if (mUserController.hasUserRestriction(
17767                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17768                         continue;
17769                     }
17770                     List<BroadcastFilter> registeredReceiversForUser =
17771                             mReceiverResolver.queryIntent(intent,
17772                                     resolvedType, false, users[i]);
17773                     if (registeredReceivers == null) {
17774                         registeredReceivers = registeredReceiversForUser;
17775                     } else if (registeredReceiversForUser != null) {
17776                         registeredReceivers.addAll(registeredReceiversForUser);
17777                     }
17778                 }
17779             } else {
17780                 registeredReceivers = mReceiverResolver.queryIntent(intent,
17781                         resolvedType, false, userId);
17782             }
17783         }
17784
17785         final boolean replacePending =
17786                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17787
17788         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17789                 + " replacePending=" + replacePending);
17790
17791         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17792         if (!ordered && NR > 0) {
17793             // If we are not serializing this broadcast, then send the
17794             // registered receivers separately so they don't wait for the
17795             // components to be launched.
17796             final BroadcastQueue queue = broadcastQueueForIntent(intent);
17797             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17798                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17799                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17800                     resultExtras, ordered, sticky, false, userId);
17801             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17802             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17803             if (!replaced) {
17804                 queue.enqueueParallelBroadcastLocked(r);
17805                 queue.scheduleBroadcastsLocked();
17806             }
17807             registeredReceivers = null;
17808             NR = 0;
17809         }
17810
17811         // Merge into one list.
17812         int ir = 0;
17813         if (receivers != null) {
17814             // A special case for PACKAGE_ADDED: do not allow the package
17815             // being added to see this broadcast.  This prevents them from
17816             // using this as a back door to get run as soon as they are
17817             // installed.  Maybe in the future we want to have a special install
17818             // broadcast or such for apps, but we'd like to deliberately make
17819             // this decision.
17820             String skipPackages[] = null;
17821             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17822                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17823                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17824                 Uri data = intent.getData();
17825                 if (data != null) {
17826                     String pkgName = data.getSchemeSpecificPart();
17827                     if (pkgName != null) {
17828                         skipPackages = new String[] { pkgName };
17829                     }
17830                 }
17831             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17832                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17833             }
17834             if (skipPackages != null && (skipPackages.length > 0)) {
17835                 for (String skipPackage : skipPackages) {
17836                     if (skipPackage != null) {
17837                         int NT = receivers.size();
17838                         for (int it=0; it<NT; it++) {
17839                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
17840                             if (curt.activityInfo.packageName.equals(skipPackage)) {
17841                                 receivers.remove(it);
17842                                 it--;
17843                                 NT--;
17844                             }
17845                         }
17846                     }
17847                 }
17848             }
17849
17850             int NT = receivers != null ? receivers.size() : 0;
17851             int it = 0;
17852             ResolveInfo curt = null;
17853             BroadcastFilter curr = null;
17854             while (it < NT && ir < NR) {
17855                 if (curt == null) {
17856                     curt = (ResolveInfo)receivers.get(it);
17857                 }
17858                 if (curr == null) {
17859                     curr = registeredReceivers.get(ir);
17860                 }
17861                 if (curr.getPriority() >= curt.priority) {
17862                     // Insert this broadcast record into the final list.
17863                     receivers.add(it, curr);
17864                     ir++;
17865                     curr = null;
17866                     it++;
17867                     NT++;
17868                 } else {
17869                     // Skip to the next ResolveInfo in the final list.
17870                     it++;
17871                     curt = null;
17872                 }
17873             }
17874         }
17875         while (ir < NR) {
17876             if (receivers == null) {
17877                 receivers = new ArrayList();
17878             }
17879             receivers.add(registeredReceivers.get(ir));
17880             ir++;
17881         }
17882
17883         if ((receivers != null && receivers.size() > 0)
17884                 || resultTo != null) {
17885             BroadcastQueue queue = broadcastQueueForIntent(intent);
17886             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17887                     callerPackage, callingPid, callingUid, resolvedType,
17888                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17889                     resultData, resultExtras, ordered, sticky, false, userId);
17890
17891             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17892                     + ": prev had " + queue.mOrderedBroadcasts.size());
17893             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17894                     "Enqueueing broadcast " + r.intent.getAction());
17895
17896             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17897             if (!replaced) {
17898                 queue.enqueueOrderedBroadcastLocked(r);
17899                 queue.scheduleBroadcastsLocked();
17900             }
17901         }
17902
17903         return ActivityManager.BROADCAST_SUCCESS;
17904     }
17905
17906     final Intent verifyBroadcastLocked(Intent intent) {
17907         // Refuse possible leaked file descriptors
17908         if (intent != null && intent.hasFileDescriptors() == true) {
17909             throw new IllegalArgumentException("File descriptors passed in Intent");
17910         }
17911
17912         int flags = intent.getFlags();
17913
17914         if (!mProcessesReady) {
17915             // if the caller really truly claims to know what they're doing, go
17916             // ahead and allow the broadcast without launching any receivers
17917             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17918                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17919             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17920                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17921                         + " before boot completion");
17922                 throw new IllegalStateException("Cannot broadcast before boot completed");
17923             }
17924         }
17925
17926         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17927             throw new IllegalArgumentException(
17928                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17929         }
17930
17931         return intent;
17932     }
17933
17934     public final int broadcastIntent(IApplicationThread caller,
17935             Intent intent, String resolvedType, IIntentReceiver resultTo,
17936             int resultCode, String resultData, Bundle resultExtras,
17937             String[] requiredPermissions, int appOp, Bundle bOptions,
17938             boolean serialized, boolean sticky, int userId) {
17939         enforceNotIsolatedCaller("broadcastIntent");
17940         synchronized(this) {
17941             intent = verifyBroadcastLocked(intent);
17942
17943             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17944             final int callingPid = Binder.getCallingPid();
17945             final int callingUid = Binder.getCallingUid();
17946             final long origId = Binder.clearCallingIdentity();
17947             int res = broadcastIntentLocked(callerApp,
17948                     callerApp != null ? callerApp.info.packageName : null,
17949                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17950                     requiredPermissions, appOp, bOptions, serialized, sticky,
17951                     callingPid, callingUid, userId);
17952             Binder.restoreCallingIdentity(origId);
17953             return res;
17954         }
17955     }
17956
17957
17958     int broadcastIntentInPackage(String packageName, int uid,
17959             Intent intent, String resolvedType, IIntentReceiver resultTo,
17960             int resultCode, String resultData, Bundle resultExtras,
17961             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17962             int userId) {
17963         synchronized(this) {
17964             intent = verifyBroadcastLocked(intent);
17965
17966             final long origId = Binder.clearCallingIdentity();
17967             String[] requiredPermissions = requiredPermission == null ? null
17968                     : new String[] {requiredPermission};
17969             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17970                     resultTo, resultCode, resultData, resultExtras,
17971                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17972                     sticky, -1, uid, userId);
17973             Binder.restoreCallingIdentity(origId);
17974             return res;
17975         }
17976     }
17977
17978     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17979         // Refuse possible leaked file descriptors
17980         if (intent != null && intent.hasFileDescriptors() == true) {
17981             throw new IllegalArgumentException("File descriptors passed in Intent");
17982         }
17983
17984         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17985                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17986
17987         synchronized(this) {
17988             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17989                     != PackageManager.PERMISSION_GRANTED) {
17990                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17991                         + Binder.getCallingPid()
17992                         + ", uid=" + Binder.getCallingUid()
17993                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17994                 Slog.w(TAG, msg);
17995                 throw new SecurityException(msg);
17996             }
17997             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17998             if (stickies != null) {
17999                 ArrayList<Intent> list = stickies.get(intent.getAction());
18000                 if (list != null) {
18001                     int N = list.size();
18002                     int i;
18003                     for (i=0; i<N; i++) {
18004                         if (intent.filterEquals(list.get(i))) {
18005                             list.remove(i);
18006                             break;
18007                         }
18008                     }
18009                     if (list.size() <= 0) {
18010                         stickies.remove(intent.getAction());
18011                     }
18012                 }
18013                 if (stickies.size() <= 0) {
18014                     mStickyBroadcasts.remove(userId);
18015                 }
18016             }
18017         }
18018     }
18019
18020     void backgroundServicesFinishedLocked(int userId) {
18021         for (BroadcastQueue queue : mBroadcastQueues) {
18022             queue.backgroundServicesFinishedLocked(userId);
18023         }
18024     }
18025
18026     public void finishReceiver(IBinder who, int resultCode, String resultData,
18027             Bundle resultExtras, boolean resultAbort, int flags) {
18028         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18029
18030         // Refuse possible leaked file descriptors
18031         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18032             throw new IllegalArgumentException("File descriptors passed in Bundle");
18033         }
18034
18035         final long origId = Binder.clearCallingIdentity();
18036         try {
18037             boolean doNext = false;
18038             BroadcastRecord r;
18039
18040             synchronized(this) {
18041                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18042                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18043                 r = queue.getMatchingOrderedReceiver(who);
18044                 if (r != null) {
18045                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18046                         resultData, resultExtras, resultAbort, true);
18047                 }
18048             }
18049
18050             if (doNext) {
18051                 r.queue.processNextBroadcast(false);
18052             }
18053             trimApplications();
18054         } finally {
18055             Binder.restoreCallingIdentity(origId);
18056         }
18057     }
18058
18059     // =========================================================
18060     // INSTRUMENTATION
18061     // =========================================================
18062
18063     public boolean startInstrumentation(ComponentName className,
18064             String profileFile, int flags, Bundle arguments,
18065             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18066             int userId, String abiOverride) {
18067         enforceNotIsolatedCaller("startInstrumentation");
18068         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18069                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18070         // Refuse possible leaked file descriptors
18071         if (arguments != null && arguments.hasFileDescriptors()) {
18072             throw new IllegalArgumentException("File descriptors passed in Bundle");
18073         }
18074
18075         synchronized(this) {
18076             InstrumentationInfo ii = null;
18077             ApplicationInfo ai = null;
18078             try {
18079                 ii = mContext.getPackageManager().getInstrumentationInfo(
18080                     className, STOCK_PM_FLAGS);
18081                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18082                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18083             } catch (PackageManager.NameNotFoundException e) {
18084             } catch (RemoteException e) {
18085             }
18086             if (ii == null) {
18087                 reportStartInstrumentationFailureLocked(watcher, className,
18088                         "Unable to find instrumentation info for: " + className);
18089                 return false;
18090             }
18091             if (ai == null) {
18092                 reportStartInstrumentationFailureLocked(watcher, className,
18093                         "Unable to find instrumentation target package: " + ii.targetPackage);
18094                 return false;
18095             }
18096             if (!ai.hasCode()) {
18097                 reportStartInstrumentationFailureLocked(watcher, className,
18098                         "Instrumentation target has no code: " + ii.targetPackage);
18099                 return false;
18100             }
18101
18102             int match = mContext.getPackageManager().checkSignatures(
18103                     ii.targetPackage, ii.packageName);
18104             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18105                 String msg = "Permission Denial: starting instrumentation "
18106                         + className + " from pid="
18107                         + Binder.getCallingPid()
18108                         + ", uid=" + Binder.getCallingPid()
18109                         + " not allowed because package " + ii.packageName
18110                         + " does not have a signature matching the target "
18111                         + ii.targetPackage;
18112                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18113                 throw new SecurityException(msg);
18114             }
18115
18116             final long origId = Binder.clearCallingIdentity();
18117             // Instrumentation can kill and relaunch even persistent processes
18118             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18119                     "start instr");
18120             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18121             app.instrumentationClass = className;
18122             app.instrumentationInfo = ai;
18123             app.instrumentationProfileFile = profileFile;
18124             app.instrumentationArguments = arguments;
18125             app.instrumentationWatcher = watcher;
18126             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18127             app.instrumentationResultClass = className;
18128             Binder.restoreCallingIdentity(origId);
18129         }
18130
18131         return true;
18132     }
18133
18134     /**
18135      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18136      * error to the logs, but if somebody is watching, send the report there too.  This enables
18137      * the "am" command to report errors with more information.
18138      *
18139      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18140      * @param cn The component name of the instrumentation.
18141      * @param report The error report.
18142      */
18143     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18144             ComponentName cn, String report) {
18145         Slog.w(TAG, report);
18146         if (watcher != null) {
18147             Bundle results = new Bundle();
18148             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18149             results.putString("Error", report);
18150             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18151         }
18152     }
18153
18154     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18155         if (app.instrumentationWatcher != null) {
18156             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18157                     app.instrumentationClass, resultCode, results);
18158         }
18159
18160         // Can't call out of the system process with a lock held, so post a message.
18161         if (app.instrumentationUiAutomationConnection != null) {
18162             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18163                     app.instrumentationUiAutomationConnection).sendToTarget();
18164         }
18165
18166         app.instrumentationWatcher = null;
18167         app.instrumentationUiAutomationConnection = null;
18168         app.instrumentationClass = null;
18169         app.instrumentationInfo = null;
18170         app.instrumentationProfileFile = null;
18171         app.instrumentationArguments = null;
18172
18173         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18174                 "finished inst");
18175     }
18176
18177     public void finishInstrumentation(IApplicationThread target,
18178             int resultCode, Bundle results) {
18179         int userId = UserHandle.getCallingUserId();
18180         // Refuse possible leaked file descriptors
18181         if (results != null && results.hasFileDescriptors()) {
18182             throw new IllegalArgumentException("File descriptors passed in Intent");
18183         }
18184
18185         synchronized(this) {
18186             ProcessRecord app = getRecordForAppLocked(target);
18187             if (app == null) {
18188                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18189                 return;
18190             }
18191             final long origId = Binder.clearCallingIdentity();
18192             finishInstrumentationLocked(app, resultCode, results);
18193             Binder.restoreCallingIdentity(origId);
18194         }
18195     }
18196
18197     // =========================================================
18198     // CONFIGURATION
18199     // =========================================================
18200
18201     public ConfigurationInfo getDeviceConfigurationInfo() {
18202         ConfigurationInfo config = new ConfigurationInfo();
18203         synchronized (this) {
18204             config.reqTouchScreen = mConfiguration.touchscreen;
18205             config.reqKeyboardType = mConfiguration.keyboard;
18206             config.reqNavigation = mConfiguration.navigation;
18207             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18208                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18209                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18210             }
18211             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18212                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18213                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18214             }
18215             config.reqGlEsVersion = GL_ES_VERSION;
18216         }
18217         return config;
18218     }
18219
18220     ActivityStack getFocusedStack() {
18221         return mStackSupervisor.getFocusedStack();
18222     }
18223
18224     @Override
18225     public int getFocusedStackId() throws RemoteException {
18226         ActivityStack focusedStack = getFocusedStack();
18227         if (focusedStack != null) {
18228             return focusedStack.getStackId();
18229         }
18230         return -1;
18231     }
18232
18233     public Configuration getConfiguration() {
18234         Configuration ci;
18235         synchronized(this) {
18236             ci = new Configuration(mConfiguration);
18237             ci.userSetLocale = false;
18238         }
18239         return ci;
18240     }
18241
18242     @Override
18243     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18244         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18245         synchronized (this) {
18246             mSuppressResizeConfigChanges = suppress;
18247         }
18248     }
18249
18250     @Override
18251     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18252         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18253         if (fromStackId == HOME_STACK_ID) {
18254             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18255         }
18256         synchronized (this) {
18257             final long origId = Binder.clearCallingIdentity();
18258             try {
18259                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18260             } finally {
18261                 Binder.restoreCallingIdentity(origId);
18262             }
18263         }
18264     }
18265
18266     @Override
18267     public void updatePersistentConfiguration(Configuration values) {
18268         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18269                 "updateConfiguration()");
18270         enforceWriteSettingsPermission("updateConfiguration()");
18271         if (values == null) {
18272             throw new NullPointerException("Configuration must not be null");
18273         }
18274
18275         int userId = UserHandle.getCallingUserId();
18276
18277         synchronized(this) {
18278             final long origId = Binder.clearCallingIdentity();
18279             updateConfigurationLocked(values, null, false, true, userId);
18280             Binder.restoreCallingIdentity(origId);
18281         }
18282     }
18283
18284     private void updateFontScaleIfNeeded() {
18285         final int currentUserId;
18286         synchronized(this) {
18287             currentUserId = mUserController.getCurrentUserIdLocked();
18288         }
18289         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18290                 FONT_SCALE, 1.0f, currentUserId);
18291         if (mConfiguration.fontScale != scaleFactor) {
18292             final Configuration configuration = mWindowManager.computeNewConfiguration();
18293             configuration.fontScale = scaleFactor;
18294             updatePersistentConfiguration(configuration);
18295         }
18296     }
18297
18298     private void enforceWriteSettingsPermission(String func) {
18299         int uid = Binder.getCallingUid();
18300         if (uid == Process.ROOT_UID) {
18301             return;
18302         }
18303
18304         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18305                 Settings.getPackageNameForUid(mContext, uid), false)) {
18306             return;
18307         }
18308
18309         String msg = "Permission Denial: " + func + " from pid="
18310                 + Binder.getCallingPid()
18311                 + ", uid=" + uid
18312                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18313         Slog.w(TAG, msg);
18314         throw new SecurityException(msg);
18315     }
18316
18317     public void updateConfiguration(Configuration values) {
18318         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319                 "updateConfiguration()");
18320
18321         synchronized(this) {
18322             if (values == null && mWindowManager != null) {
18323                 // sentinel: fetch the current configuration from the window manager
18324                 values = mWindowManager.computeNewConfiguration();
18325             }
18326
18327             if (mWindowManager != null) {
18328                 mProcessList.applyDisplaySize(mWindowManager);
18329             }
18330
18331             final long origId = Binder.clearCallingIdentity();
18332             if (values != null) {
18333                 Settings.System.clearConfiguration(values);
18334             }
18335             updateConfigurationLocked(values, null, false);
18336             Binder.restoreCallingIdentity(origId);
18337         }
18338     }
18339
18340     void updateUserConfigurationLocked() {
18341         Configuration configuration = new Configuration(mConfiguration);
18342         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18343                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18344         updateConfigurationLocked(configuration, null, false);
18345     }
18346
18347     boolean updateConfigurationLocked(Configuration values,
18348             ActivityRecord starting, boolean initLocale) {
18349         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18350         return updateConfigurationLocked(values, starting, initLocale, false,
18351                 UserHandle.USER_NULL);
18352     }
18353
18354     // To cache the list of supported system locales
18355     private String[] mSupportedSystemLocales = null;
18356
18357     /**
18358      * Do either or both things: (1) change the current configuration, and (2)
18359      * make sure the given activity is running with the (now) current
18360      * configuration.  Returns true if the activity has been left running, or
18361      * false if <var>starting</var> is being destroyed to match the new
18362      * configuration.
18363      *
18364      * @param userId is only used when persistent parameter is set to true to persist configuration
18365      *               for that particular user
18366      */
18367     private boolean updateConfigurationLocked(Configuration values,
18368             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18369         int changes = 0;
18370
18371         if (mWindowManager != null) {
18372             mWindowManager.deferSurfaceLayout();
18373         }
18374         if (values != null) {
18375             Configuration newConfig = new Configuration(mConfiguration);
18376             changes = newConfig.updateFrom(values);
18377             if (changes != 0) {
18378                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18379                         "Updating configuration to: " + values);
18380
18381                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18382
18383                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18384                     final LocaleList locales = values.getLocales();
18385                     int bestLocaleIndex = 0;
18386                     if (locales.size() > 1) {
18387                         if (mSupportedSystemLocales == null) {
18388                             mSupportedSystemLocales =
18389                                     Resources.getSystem().getAssets().getLocales();
18390                         }
18391                         bestLocaleIndex = Math.max(0,
18392                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
18393                     }
18394                     SystemProperties.set("persist.sys.locale",
18395                             locales.get(bestLocaleIndex).toLanguageTag());
18396                     LocaleList.setDefault(locales, bestLocaleIndex);
18397                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18398                             locales.get(bestLocaleIndex)));
18399                 }
18400
18401                 mConfigurationSeq++;
18402                 if (mConfigurationSeq <= 0) {
18403                     mConfigurationSeq = 1;
18404                 }
18405                 newConfig.seq = mConfigurationSeq;
18406                 mConfiguration = newConfig;
18407                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18408                 mUsageStatsService.reportConfigurationChange(newConfig,
18409                         mUserController.getCurrentUserIdLocked());
18410                 //mUsageStatsService.noteStartConfig(newConfig);
18411
18412                 final Configuration configCopy = new Configuration(mConfiguration);
18413
18414                 // TODO: If our config changes, should we auto dismiss any currently
18415                 // showing dialogs?
18416                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18417
18418                 AttributeCache ac = AttributeCache.instance();
18419                 if (ac != null) {
18420                     ac.updateConfiguration(configCopy);
18421                 }
18422
18423                 // Make sure all resources in our process are updated
18424                 // right now, so that anyone who is going to retrieve
18425                 // resource values after we return will be sure to get
18426                 // the new ones.  This is especially important during
18427                 // boot, where the first config change needs to guarantee
18428                 // all resources have that config before following boot
18429                 // code is executed.
18430                 mSystemThread.applyConfigurationToResources(configCopy);
18431
18432                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18433                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18434                     msg.obj = new Configuration(configCopy);
18435                     msg.arg1 = userId;
18436                     mHandler.sendMessage(msg);
18437                 }
18438
18439                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18440                 if (isDensityChange) {
18441                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18442                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18443                 }
18444
18445                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18446                     ProcessRecord app = mLruProcesses.get(i);
18447                     try {
18448                         if (app.thread != null) {
18449                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18450                                     + app.processName + " new config " + mConfiguration);
18451                             app.thread.scheduleConfigurationChanged(configCopy);
18452                         }
18453                     } catch (Exception e) {
18454                     }
18455                 }
18456                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18457                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18458                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
18459                         | Intent.FLAG_RECEIVER_FOREGROUND);
18460                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18461                         null, AppOpsManager.OP_NONE, null, false, false,
18462                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18463                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18464                     // Tell the shortcut manager that the system locale changed.  It needs to know
18465                     // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18466                     // we "push" from here, rather than having the service listen to the broadcast.
18467                     final ShortcutServiceInternal shortcutService =
18468                             LocalServices.getService(ShortcutServiceInternal.class);
18469                     if (shortcutService != null) {
18470                         shortcutService.onSystemLocaleChangedNoLock();
18471                     }
18472
18473                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18474                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18475                     if (!mProcessesReady) {
18476                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18477                     }
18478                     broadcastIntentLocked(null, null, intent,
18479                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18480                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18481                 }
18482             }
18483             // Update the configuration with WM first and check if any of the stacks need to be
18484             // resized due to the configuration change. If so, resize the stacks now and do any
18485             // relaunches if necessary. This way we don't need to relaunch again below in
18486             // ensureActivityConfigurationLocked().
18487             if (mWindowManager != null) {
18488                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18489                 if (resizedStacks != null) {
18490                     for (int stackId : resizedStacks) {
18491                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18492                         mStackSupervisor.resizeStackLocked(
18493                                 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18494                     }
18495                 }
18496             }
18497         }
18498
18499         boolean kept = true;
18500         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18501         // mainStack is null during startup.
18502         if (mainStack != null) {
18503             if (changes != 0 && starting == null) {
18504                 // If the configuration changed, and the caller is not already
18505                 // in the process of starting an activity, then find the top
18506                 // activity to check if its configuration needs to change.
18507                 starting = mainStack.topRunningActivityLocked();
18508             }
18509
18510             if (starting != null) {
18511                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18512                 // And we need to make sure at this point that all other activities
18513                 // are made visible with the correct configuration.
18514                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18515                         !PRESERVE_WINDOWS);
18516             }
18517         }
18518         if (mWindowManager != null) {
18519             mWindowManager.continueSurfaceLayout();
18520         }
18521         return kept;
18522     }
18523
18524     /**
18525      * Decide based on the configuration whether we should shouw the ANR,
18526      * crash, etc dialogs.  The idea is that if there is no affordnace to
18527      * press the on-screen buttons, we shouldn't show the dialog.
18528      *
18529      * A thought: SystemUI might also want to get told about this, the Power
18530      * dialog / global actions also might want different behaviors.
18531      */
18532     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18533         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18534                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18535                                    && config.navigation == Configuration.NAVIGATION_NONAV);
18536         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18537                                     == Configuration.UI_MODE_TYPE_CAR);
18538         return inputMethodExists && uiIsNotCarType && !inVrMode;
18539     }
18540
18541     @Override
18542     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18543         synchronized (this) {
18544             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18545             if (srec != null) {
18546                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18547             }
18548         }
18549         return false;
18550     }
18551
18552     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18553             Intent resultData) {
18554
18555         synchronized (this) {
18556             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18557             if (r != null) {
18558                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18559             }
18560             return false;
18561         }
18562     }
18563
18564     public int getLaunchedFromUid(IBinder activityToken) {
18565         ActivityRecord srec;
18566         synchronized (this) {
18567             srec = ActivityRecord.forTokenLocked(activityToken);
18568         }
18569         if (srec == null) {
18570             return -1;
18571         }
18572         return srec.launchedFromUid;
18573     }
18574
18575     public String getLaunchedFromPackage(IBinder activityToken) {
18576         ActivityRecord srec;
18577         synchronized (this) {
18578             srec = ActivityRecord.forTokenLocked(activityToken);
18579         }
18580         if (srec == null) {
18581             return null;
18582         }
18583         return srec.launchedFromPackage;
18584     }
18585
18586     // =========================================================
18587     // LIFETIME MANAGEMENT
18588     // =========================================================
18589
18590     // Returns which broadcast queue the app is the current [or imminent] receiver
18591     // on, or 'null' if the app is not an active broadcast recipient.
18592     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18593         BroadcastRecord r = app.curReceiver;
18594         if (r != null) {
18595             return r.queue;
18596         }
18597
18598         // It's not the current receiver, but it might be starting up to become one
18599         synchronized (this) {
18600             for (BroadcastQueue queue : mBroadcastQueues) {
18601                 r = queue.mPendingBroadcast;
18602                 if (r != null && r.curApp == app) {
18603                     // found it; report which queue it's in
18604                     return queue;
18605                 }
18606             }
18607         }
18608
18609         return null;
18610     }
18611
18612     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18613             int targetUid, ComponentName targetComponent, String targetProcess) {
18614         if (!mTrackingAssociations) {
18615             return null;
18616         }
18617         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18618                 = mAssociations.get(targetUid);
18619         if (components == null) {
18620             components = new ArrayMap<>();
18621             mAssociations.put(targetUid, components);
18622         }
18623         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18624         if (sourceUids == null) {
18625             sourceUids = new SparseArray<>();
18626             components.put(targetComponent, sourceUids);
18627         }
18628         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18629         if (sourceProcesses == null) {
18630             sourceProcesses = new ArrayMap<>();
18631             sourceUids.put(sourceUid, sourceProcesses);
18632         }
18633         Association ass = sourceProcesses.get(sourceProcess);
18634         if (ass == null) {
18635             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18636                     targetProcess);
18637             sourceProcesses.put(sourceProcess, ass);
18638         }
18639         ass.mCount++;
18640         ass.mNesting++;
18641         if (ass.mNesting == 1) {
18642             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18643             ass.mLastState = sourceState;
18644         }
18645         return ass;
18646     }
18647
18648     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18649             ComponentName targetComponent) {
18650         if (!mTrackingAssociations) {
18651             return;
18652         }
18653         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18654                 = mAssociations.get(targetUid);
18655         if (components == null) {
18656             return;
18657         }
18658         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18659         if (sourceUids == null) {
18660             return;
18661         }
18662         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18663         if (sourceProcesses == null) {
18664             return;
18665         }
18666         Association ass = sourceProcesses.get(sourceProcess);
18667         if (ass == null || ass.mNesting <= 0) {
18668             return;
18669         }
18670         ass.mNesting--;
18671         if (ass.mNesting == 0) {
18672             long uptime = SystemClock.uptimeMillis();
18673             ass.mTime += uptime - ass.mStartTime;
18674             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18675                     += uptime - ass.mLastStateUptime;
18676             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18677         }
18678     }
18679
18680     private void noteUidProcessState(final int uid, final int state) {
18681         mBatteryStatsService.noteUidProcessState(uid, state);
18682         if (mTrackingAssociations) {
18683             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18684                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18685                         = mAssociations.valueAt(i1);
18686                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18687                     SparseArray<ArrayMap<String, Association>> sourceUids
18688                             = targetComponents.valueAt(i2);
18689                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18690                     if (sourceProcesses != null) {
18691                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18692                             Association ass = sourceProcesses.valueAt(i4);
18693                             if (ass.mNesting >= 1) {
18694                                 // currently associated
18695                                 long uptime = SystemClock.uptimeMillis();
18696                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18697                                         += uptime - ass.mLastStateUptime;
18698                                 ass.mLastState = state;
18699                                 ass.mLastStateUptime = uptime;
18700                             }
18701                         }
18702                     }
18703                 }
18704             }
18705         }
18706     }
18707
18708     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18709             boolean doingAll, long now) {
18710         if (mAdjSeq == app.adjSeq) {
18711             // This adjustment has already been computed.
18712             return app.curRawAdj;
18713         }
18714
18715         if (app.thread == null) {
18716             app.adjSeq = mAdjSeq;
18717             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18718             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18719             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18720         }
18721
18722         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18723         app.adjSource = null;
18724         app.adjTarget = null;
18725         app.empty = false;
18726         app.cached = false;
18727
18728         final int activitiesSize = app.activities.size();
18729
18730         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18731             // The max adjustment doesn't allow this app to be anything
18732             // below foreground, so it is not worth doing work for it.
18733             app.adjType = "fixed";
18734             app.adjSeq = mAdjSeq;
18735             app.curRawAdj = app.maxAdj;
18736             app.foregroundActivities = false;
18737             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18738             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18739             // System processes can do UI, and when they do we want to have
18740             // them trim their memory after the user leaves the UI.  To
18741             // facilitate this, here we need to determine whether or not it
18742             // is currently showing UI.
18743             app.systemNoUi = true;
18744             if (app == TOP_APP) {
18745                 app.systemNoUi = false;
18746                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18747                 app.adjType = "pers-top-activity";
18748             } else if (activitiesSize > 0) {
18749                 for (int j = 0; j < activitiesSize; j++) {
18750                     final ActivityRecord r = app.activities.get(j);
18751                     if (r.visible) {
18752                         app.systemNoUi = false;
18753                     }
18754                 }
18755             }
18756             if (!app.systemNoUi) {
18757                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18758             }
18759             return (app.curAdj=app.maxAdj);
18760         }
18761
18762         app.systemNoUi = false;
18763
18764         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18765
18766         // Determine the importance of the process, starting with most
18767         // important to least, and assign an appropriate OOM adjustment.
18768         int adj;
18769         int schedGroup;
18770         int procState;
18771         boolean foregroundActivities = false;
18772         BroadcastQueue queue;
18773         if (app == TOP_APP) {
18774             // The last app on the list is the foreground app.
18775             adj = ProcessList.FOREGROUND_APP_ADJ;
18776             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18777             app.adjType = "top-activity";
18778             foregroundActivities = true;
18779             procState = PROCESS_STATE_CUR_TOP;
18780         } else if (app.instrumentationClass != null) {
18781             // Don't want to kill running instrumentation.
18782             adj = ProcessList.FOREGROUND_APP_ADJ;
18783             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18784             app.adjType = "instrumentation";
18785             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18786         } else if ((queue = isReceivingBroadcast(app)) != null) {
18787             // An app that is currently receiving a broadcast also
18788             // counts as being in the foreground for OOM killer purposes.
18789             // It's placed in a sched group based on the nature of the
18790             // broadcast as reflected by which queue it's active in.
18791             adj = ProcessList.FOREGROUND_APP_ADJ;
18792             schedGroup = (queue == mFgBroadcastQueue)
18793                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18794             app.adjType = "broadcast";
18795             procState = ActivityManager.PROCESS_STATE_RECEIVER;
18796         } else if (app.executingServices.size() > 0) {
18797             // An app that is currently executing a service callback also
18798             // counts as being in the foreground.
18799             adj = ProcessList.FOREGROUND_APP_ADJ;
18800             schedGroup = app.execServicesFg ?
18801                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18802             app.adjType = "exec-service";
18803             procState = ActivityManager.PROCESS_STATE_SERVICE;
18804             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18805         } else {
18806             // As far as we know the process is empty.  We may change our mind later.
18807             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18808             // At this point we don't actually know the adjustment.  Use the cached adj
18809             // value that the caller wants us to.
18810             adj = cachedAdj;
18811             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18812             app.cached = true;
18813             app.empty = true;
18814             app.adjType = "cch-empty";
18815         }
18816
18817         // Examine all activities if not already foreground.
18818         if (!foregroundActivities && activitiesSize > 0) {
18819             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18820             for (int j = 0; j < activitiesSize; j++) {
18821                 final ActivityRecord r = app.activities.get(j);
18822                 if (r.app != app) {
18823                     Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18824                             + " instead of expected " + app);
18825                     if (r.app == null || (r.app.uid == app.uid)) {
18826                         // Only fix things up when they look sane
18827                         r.app = app;
18828                     } else {
18829                         continue;
18830                     }
18831                 }
18832                 if (r.visible) {
18833                     // App has a visible activity; only upgrade adjustment.
18834                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18835                         adj = ProcessList.VISIBLE_APP_ADJ;
18836                         app.adjType = "visible";
18837                     }
18838                     if (procState > PROCESS_STATE_CUR_TOP) {
18839                         procState = PROCESS_STATE_CUR_TOP;
18840                     }
18841                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18842                     app.cached = false;
18843                     app.empty = false;
18844                     foregroundActivities = true;
18845                     if (r.task != null && minLayer > 0) {
18846                         final int layer = r.task.mLayerRank;
18847                         if (layer >= 0 && minLayer > layer) {
18848                             minLayer = layer;
18849                         }
18850                     }
18851                     break;
18852                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18853                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18854                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18855                         app.adjType = "pausing";
18856                     }
18857                     if (procState > PROCESS_STATE_CUR_TOP) {
18858                         procState = PROCESS_STATE_CUR_TOP;
18859                     }
18860                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18861                     app.cached = false;
18862                     app.empty = false;
18863                     foregroundActivities = true;
18864                 } else if (r.state == ActivityState.STOPPING) {
18865                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18866                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18867                         app.adjType = "stopping";
18868                     }
18869                     // For the process state, we will at this point consider the
18870                     // process to be cached.  It will be cached either as an activity
18871                     // or empty depending on whether the activity is finishing.  We do
18872                     // this so that we can treat the process as cached for purposes of
18873                     // memory trimming (determing current memory level, trim command to
18874                     // send to process) since there can be an arbitrary number of stopping
18875                     // processes and they should soon all go into the cached state.
18876                     if (!r.finishing) {
18877                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18878                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18879                         }
18880                     }
18881                     app.cached = false;
18882                     app.empty = false;
18883                     foregroundActivities = true;
18884                 } else {
18885                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18886                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18887                         app.adjType = "cch-act";
18888                     }
18889                 }
18890             }
18891             if (adj == ProcessList.VISIBLE_APP_ADJ) {
18892                 adj += minLayer;
18893             }
18894         }
18895
18896         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18897                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18898             if (app.foregroundServices) {
18899                 // The user is aware of this app, so make it visible.
18900                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18901                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18902                 app.cached = false;
18903                 app.adjType = "fg-service";
18904                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18905             } else if (app.forcingToForeground != null) {
18906                 // The user is aware of this app, so make it visible.
18907                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18908                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18909                 app.cached = false;
18910                 app.adjType = "force-fg";
18911                 app.adjSource = app.forcingToForeground;
18912                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18913             }
18914         }
18915
18916         if (app == mHeavyWeightProcess) {
18917             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18918                 // We don't want to kill the current heavy-weight process.
18919                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18920                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18921                 app.cached = false;
18922                 app.adjType = "heavy";
18923             }
18924             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18925                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18926             }
18927         }
18928
18929         if (app == mHomeProcess) {
18930             if (adj > ProcessList.HOME_APP_ADJ) {
18931                 // This process is hosting what we currently consider to be the
18932                 // home app, so we don't want to let it go into the background.
18933                 adj = ProcessList.HOME_APP_ADJ;
18934                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18935                 app.cached = false;
18936                 app.adjType = "home";
18937             }
18938             if (procState > ActivityManager.PROCESS_STATE_HOME) {
18939                 procState = ActivityManager.PROCESS_STATE_HOME;
18940             }
18941         }
18942
18943         if (app == mPreviousProcess && app.activities.size() > 0) {
18944             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18945                 // This was the previous process that showed UI to the user.
18946                 // We want to try to keep it around more aggressively, to give
18947                 // a good experience around switching between two apps.
18948                 adj = ProcessList.PREVIOUS_APP_ADJ;
18949                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18950                 app.cached = false;
18951                 app.adjType = "previous";
18952             }
18953             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18954                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18955             }
18956         }
18957
18958         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18959                 + " reason=" + app.adjType);
18960
18961         // By default, we use the computed adjustment.  It may be changed if
18962         // there are applications dependent on our services or providers, but
18963         // this gives us a baseline and makes sure we don't get into an
18964         // infinite recursion.
18965         app.adjSeq = mAdjSeq;
18966         app.curRawAdj = adj;
18967         app.hasStartedServices = false;
18968
18969         if (mBackupTarget != null && app == mBackupTarget.app) {
18970             // If possible we want to avoid killing apps while they're being backed up
18971             if (adj > ProcessList.BACKUP_APP_ADJ) {
18972                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18973                 adj = ProcessList.BACKUP_APP_ADJ;
18974                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18975                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18976                 }
18977                 app.adjType = "backup";
18978                 app.cached = false;
18979             }
18980             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18981                 procState = ActivityManager.PROCESS_STATE_BACKUP;
18982             }
18983         }
18984
18985         boolean mayBeTop = false;
18986
18987         for (int is = app.services.size()-1;
18988                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18989                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18990                         || procState > ActivityManager.PROCESS_STATE_TOP);
18991                 is--) {
18992             ServiceRecord s = app.services.valueAt(is);
18993             if (s.startRequested) {
18994                 app.hasStartedServices = true;
18995                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18996                     procState = ActivityManager.PROCESS_STATE_SERVICE;
18997                 }
18998                 if (app.hasShownUi && app != mHomeProcess) {
18999                     // If this process has shown some UI, let it immediately
19000                     // go to the LRU list because it may be pretty heavy with
19001                     // UI stuff.  We'll tag it with a label just to help
19002                     // debug and understand what is going on.
19003                     if (adj > ProcessList.SERVICE_ADJ) {
19004                         app.adjType = "cch-started-ui-services";
19005                     }
19006                 } else {
19007                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19008                         // This service has seen some activity within
19009                         // recent memory, so we will keep its process ahead
19010                         // of the background processes.
19011                         if (adj > ProcessList.SERVICE_ADJ) {
19012                             adj = ProcessList.SERVICE_ADJ;
19013                             app.adjType = "started-services";
19014                             app.cached = false;
19015                         }
19016                     }
19017                     // If we have let the service slide into the background
19018                     // state, still have some text describing what it is doing
19019                     // even though the service no longer has an impact.
19020                     if (adj > ProcessList.SERVICE_ADJ) {
19021                         app.adjType = "cch-started-services";
19022                     }
19023                 }
19024             }
19025             for (int conni = s.connections.size()-1;
19026                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19027                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19028                             || procState > ActivityManager.PROCESS_STATE_TOP);
19029                     conni--) {
19030                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19031                 for (int i = 0;
19032                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19033                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19034                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19035                         i++) {
19036                     // XXX should compute this based on the max of
19037                     // all connected clients.
19038                     ConnectionRecord cr = clist.get(i);
19039                     if (cr.binding.client == app) {
19040                         // Binding to ourself is not interesting.
19041                         continue;
19042                     }
19043                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19044                         ProcessRecord client = cr.binding.client;
19045                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19046                                 TOP_APP, doingAll, now);
19047                         int clientProcState = client.curProcState;
19048                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19049                             // If the other app is cached for any reason, for purposes here
19050                             // we are going to consider it empty.  The specific cached state
19051                             // doesn't propagate except under certain conditions.
19052                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19053                         }
19054                         String adjType = null;
19055                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19056                             // Not doing bind OOM management, so treat
19057                             // this guy more like a started service.
19058                             if (app.hasShownUi && app != mHomeProcess) {
19059                                 // If this process has shown some UI, let it immediately
19060                                 // go to the LRU list because it may be pretty heavy with
19061                                 // UI stuff.  We'll tag it with a label just to help
19062                                 // debug and understand what is going on.
19063                                 if (adj > clientAdj) {
19064                                     adjType = "cch-bound-ui-services";
19065                                 }
19066                                 app.cached = false;
19067                                 clientAdj = adj;
19068                                 clientProcState = procState;
19069                             } else {
19070                                 if (now >= (s.lastActivity
19071                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19072                                     // This service has not seen activity within
19073                                     // recent memory, so allow it to drop to the
19074                                     // LRU list if there is no other reason to keep
19075                                     // it around.  We'll also tag it with a label just
19076                                     // to help debug and undertand what is going on.
19077                                     if (adj > clientAdj) {
19078                                         adjType = "cch-bound-services";
19079                                     }
19080                                     clientAdj = adj;
19081                                 }
19082                             }
19083                         }
19084                         if (adj > clientAdj) {
19085                             // If this process has recently shown UI, and
19086                             // the process that is binding to it is less
19087                             // important than being visible, then we don't
19088                             // care about the binding as much as we care
19089                             // about letting this process get into the LRU
19090                             // list to be killed and restarted if needed for
19091                             // memory.
19092                             if (app.hasShownUi && app != mHomeProcess
19093                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19094                                 adjType = "cch-bound-ui-services";
19095                             } else {
19096                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19097                                         |Context.BIND_IMPORTANT)) != 0) {
19098                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19099                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19100                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19101                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19102                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19103                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19104                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19105                                     adj = clientAdj;
19106                                 } else {
19107                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19108                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19109                                     }
19110                                 }
19111                                 if (!client.cached) {
19112                                     app.cached = false;
19113                                 }
19114                                 adjType = "service";
19115                             }
19116                         }
19117                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19118                             // This will treat important bound services identically to
19119                             // the top app, which may behave differently than generic
19120                             // foreground work.
19121                             if (client.curSchedGroup > schedGroup) {
19122                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19123                                     schedGroup = client.curSchedGroup;
19124                                 } else {
19125                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19126                                 }
19127                             }
19128                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19129                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19130                                     // Special handling of clients who are in the top state.
19131                                     // We *may* want to consider this process to be in the
19132                                     // top state as well, but only if there is not another
19133                                     // reason for it to be running.  Being on the top is a
19134                                     // special state, meaning you are specifically running
19135                                     // for the current top app.  If the process is already
19136                                     // running in the background for some other reason, it
19137                                     // is more important to continue considering it to be
19138                                     // in the background state.
19139                                     mayBeTop = true;
19140                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19141                                 } else {
19142                                     // Special handling for above-top states (persistent
19143                                     // processes).  These should not bring the current process
19144                                     // into the top state, since they are not on top.  Instead
19145                                     // give them the best state after that.
19146                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19147                                         clientProcState =
19148                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19149                                     } else if (mWakefulness
19150                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19151                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19152                                                     != 0) {
19153                                         clientProcState =
19154                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19155                                     } else {
19156                                         clientProcState =
19157                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19158                                     }
19159                                 }
19160                             }
19161                         } else {
19162                             if (clientProcState <
19163                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19164                                 clientProcState =
19165                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19166                             }
19167                         }
19168                         if (procState > clientProcState) {
19169                             procState = clientProcState;
19170                         }
19171                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19172                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19173                             app.pendingUiClean = true;
19174                         }
19175                         if (adjType != null) {
19176                             app.adjType = adjType;
19177                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19178                                     .REASON_SERVICE_IN_USE;
19179                             app.adjSource = cr.binding.client;
19180                             app.adjSourceProcState = clientProcState;
19181                             app.adjTarget = s.name;
19182                         }
19183                     }
19184                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19185                         app.treatLikeActivity = true;
19186                     }
19187                     final ActivityRecord a = cr.activity;
19188                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19189                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19190                             (a.visible || a.state == ActivityState.RESUMED ||
19191                              a.state == ActivityState.PAUSING)) {
19192                             adj = ProcessList.FOREGROUND_APP_ADJ;
19193                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19194                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19195                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19196                                 } else {
19197                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19198                                 }
19199                             }
19200                             app.cached = false;
19201                             app.adjType = "service";
19202                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19203                                     .REASON_SERVICE_IN_USE;
19204                             app.adjSource = a;
19205                             app.adjSourceProcState = procState;
19206                             app.adjTarget = s.name;
19207                         }
19208                     }
19209                 }
19210             }
19211         }
19212
19213         for (int provi = app.pubProviders.size()-1;
19214                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19215                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19216                         || procState > ActivityManager.PROCESS_STATE_TOP);
19217                 provi--) {
19218             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19219             for (int i = cpr.connections.size()-1;
19220                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19221                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19222                             || procState > ActivityManager.PROCESS_STATE_TOP);
19223                     i--) {
19224                 ContentProviderConnection conn = cpr.connections.get(i);
19225                 ProcessRecord client = conn.client;
19226                 if (client == app) {
19227                     // Being our own client is not interesting.
19228                     continue;
19229                 }
19230                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19231                 int clientProcState = client.curProcState;
19232                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19233                     // If the other app is cached for any reason, for purposes here
19234                     // we are going to consider it empty.
19235                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19236                 }
19237                 if (adj > clientAdj) {
19238                     if (app.hasShownUi && app != mHomeProcess
19239                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19240                         app.adjType = "cch-ui-provider";
19241                     } else {
19242                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19243                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19244                         app.adjType = "provider";
19245                     }
19246                     app.cached &= client.cached;
19247                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19248                             .REASON_PROVIDER_IN_USE;
19249                     app.adjSource = client;
19250                     app.adjSourceProcState = clientProcState;
19251                     app.adjTarget = cpr.name;
19252                 }
19253                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19254                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19255                         // Special handling of clients who are in the top state.
19256                         // We *may* want to consider this process to be in the
19257                         // top state as well, but only if there is not another
19258                         // reason for it to be running.  Being on the top is a
19259                         // special state, meaning you are specifically running
19260                         // for the current top app.  If the process is already
19261                         // running in the background for some other reason, it
19262                         // is more important to continue considering it to be
19263                         // in the background state.
19264                         mayBeTop = true;
19265                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19266                     } else {
19267                         // Special handling for above-top states (persistent
19268                         // processes).  These should not bring the current process
19269                         // into the top state, since they are not on top.  Instead
19270                         // give them the best state after that.
19271                         clientProcState =
19272                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19273                     }
19274                 }
19275                 if (procState > clientProcState) {
19276                     procState = clientProcState;
19277                 }
19278                 if (client.curSchedGroup > schedGroup) {
19279                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19280                 }
19281             }
19282             // If the provider has external (non-framework) process
19283             // dependencies, ensure that its adjustment is at least
19284             // FOREGROUND_APP_ADJ.
19285             if (cpr.hasExternalProcessHandles()) {
19286                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19287                     adj = ProcessList.FOREGROUND_APP_ADJ;
19288                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19289                     app.cached = false;
19290                     app.adjType = "provider";
19291                     app.adjTarget = cpr.name;
19292                 }
19293                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19294                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19295                 }
19296             }
19297         }
19298
19299         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19300             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19301                 adj = ProcessList.PREVIOUS_APP_ADJ;
19302                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19303                 app.cached = false;
19304                 app.adjType = "provider";
19305             }
19306             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19307                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19308             }
19309         }
19310
19311         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19312             // A client of one of our services or providers is in the top state.  We
19313             // *may* want to be in the top state, but not if we are already running in
19314             // the background for some other reason.  For the decision here, we are going
19315             // to pick out a few specific states that we want to remain in when a client
19316             // is top (states that tend to be longer-term) and otherwise allow it to go
19317             // to the top state.
19318             switch (procState) {
19319                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19320                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19321                 case ActivityManager.PROCESS_STATE_SERVICE:
19322                     // These all are longer-term states, so pull them up to the top
19323                     // of the background states, but not all the way to the top state.
19324                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19325                     break;
19326                 default:
19327                     // Otherwise, top is a better choice, so take it.
19328                     procState = ActivityManager.PROCESS_STATE_TOP;
19329                     break;
19330             }
19331         }
19332
19333         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19334             if (app.hasClientActivities) {
19335                 // This is a cached process, but with client activities.  Mark it so.
19336                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19337                 app.adjType = "cch-client-act";
19338             } else if (app.treatLikeActivity) {
19339                 // This is a cached process, but somebody wants us to treat it like it has
19340                 // an activity, okay!
19341                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19342                 app.adjType = "cch-as-act";
19343             }
19344         }
19345
19346         if (adj == ProcessList.SERVICE_ADJ) {
19347             if (doingAll) {
19348                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19349                 mNewNumServiceProcs++;
19350                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19351                 if (!app.serviceb) {
19352                     // This service isn't far enough down on the LRU list to
19353                     // normally be a B service, but if we are low on RAM and it
19354                     // is large we want to force it down since we would prefer to
19355                     // keep launcher over it.
19356                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19357                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19358                         app.serviceHighRam = true;
19359                         app.serviceb = true;
19360                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19361                     } else {
19362                         mNewNumAServiceProcs++;
19363                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19364                     }
19365                 } else {
19366                     app.serviceHighRam = false;
19367                 }
19368             }
19369             if (app.serviceb) {
19370                 adj = ProcessList.SERVICE_B_ADJ;
19371             }
19372         }
19373
19374         app.curRawAdj = adj;
19375
19376         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19377         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19378         if (adj > app.maxAdj) {
19379             adj = app.maxAdj;
19380             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19381                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19382             }
19383         }
19384
19385         // Do final modification to adj.  Everything we do between here and applying
19386         // the final setAdj must be done in this function, because we will also use
19387         // it when computing the final cached adj later.  Note that we don't need to
19388         // worry about this for max adj above, since max adj will always be used to
19389         // keep it out of the cached vaues.
19390         app.curAdj = app.modifyRawOomAdj(adj);
19391         app.curSchedGroup = schedGroup;
19392         app.curProcState = procState;
19393         app.foregroundActivities = foregroundActivities;
19394
19395         return app.curRawAdj;
19396     }
19397
19398     /**
19399      * Record new PSS sample for a process.
19400      */
19401     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19402             long now) {
19403         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19404                 swapPss * 1024);
19405         proc.lastPssTime = now;
19406         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19407         if (DEBUG_PSS) Slog.d(TAG_PSS,
19408                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19409                 + " state=" + ProcessList.makeProcStateString(procState));
19410         if (proc.initialIdlePss == 0) {
19411             proc.initialIdlePss = pss;
19412         }
19413         proc.lastPss = pss;
19414         proc.lastSwapPss = swapPss;
19415         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19416             proc.lastCachedPss = pss;
19417             proc.lastCachedSwapPss = swapPss;
19418         }
19419
19420         final SparseArray<Pair<Long, String>> watchUids
19421                 = mMemWatchProcesses.getMap().get(proc.processName);
19422         Long check = null;
19423         if (watchUids != null) {
19424             Pair<Long, String> val = watchUids.get(proc.uid);
19425             if (val == null) {
19426                 val = watchUids.get(0);
19427             }
19428             if (val != null) {
19429                 check = val.first;
19430             }
19431         }
19432         if (check != null) {
19433             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19434                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19435                 if (!isDebuggable) {
19436                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19437                         isDebuggable = true;
19438                     }
19439                 }
19440                 if (isDebuggable) {
19441                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19442                     final ProcessRecord myProc = proc;
19443                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
19444                     mMemWatchDumpProcName = proc.processName;
19445                     mMemWatchDumpFile = heapdumpFile.toString();
19446                     mMemWatchDumpPid = proc.pid;
19447                     mMemWatchDumpUid = proc.uid;
19448                     BackgroundThread.getHandler().post(new Runnable() {
19449                         @Override
19450                         public void run() {
19451                             revokeUriPermission(ActivityThread.currentActivityThread()
19452                                             .getApplicationThread(),
19453                                     DumpHeapActivity.JAVA_URI,
19454                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
19455                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19456                                     UserHandle.myUserId());
19457                             ParcelFileDescriptor fd = null;
19458                             try {
19459                                 heapdumpFile.delete();
19460                                 fd = ParcelFileDescriptor.open(heapdumpFile,
19461                                         ParcelFileDescriptor.MODE_CREATE |
19462                                                 ParcelFileDescriptor.MODE_TRUNCATE |
19463                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
19464                                                 ParcelFileDescriptor.MODE_APPEND);
19465                                 IApplicationThread thread = myProc.thread;
19466                                 if (thread != null) {
19467                                     try {
19468                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
19469                                                 "Requesting dump heap from "
19470                                                 + myProc + " to " + heapdumpFile);
19471                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
19472                                     } catch (RemoteException e) {
19473                                     }
19474                                 }
19475                             } catch (FileNotFoundException e) {
19476                                 e.printStackTrace();
19477                             } finally {
19478                                 if (fd != null) {
19479                                     try {
19480                                         fd.close();
19481                                     } catch (IOException e) {
19482                                     }
19483                                 }
19484                             }
19485                         }
19486                     });
19487                 } else {
19488                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19489                             + ", but debugging not enabled");
19490                 }
19491             }
19492         }
19493     }
19494
19495     /**
19496      * Schedule PSS collection of a process.
19497      */
19498     void requestPssLocked(ProcessRecord proc, int procState) {
19499         if (mPendingPssProcesses.contains(proc)) {
19500             return;
19501         }
19502         if (mPendingPssProcesses.size() == 0) {
19503             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19504         }
19505         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19506         proc.pssProcState = procState;
19507         mPendingPssProcesses.add(proc);
19508     }
19509
19510     /**
19511      * Schedule PSS collection of all processes.
19512      */
19513     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19514         if (!always) {
19515             if (now < (mLastFullPssTime +
19516                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19517                 return;
19518             }
19519         }
19520         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19521         mLastFullPssTime = now;
19522         mFullPssPending = true;
19523         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19524         mPendingPssProcesses.clear();
19525         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19526             ProcessRecord app = mLruProcesses.get(i);
19527             if (app.thread == null
19528                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19529                 continue;
19530             }
19531             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19532                 app.pssProcState = app.setProcState;
19533                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19534                         mTestPssMode, isSleeping(), now);
19535                 mPendingPssProcesses.add(app);
19536             }
19537         }
19538         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19539     }
19540
19541     public void setTestPssMode(boolean enabled) {
19542         synchronized (this) {
19543             mTestPssMode = enabled;
19544             if (enabled) {
19545                 // Whenever we enable the mode, we want to take a snapshot all of current
19546                 // process mem use.
19547                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19548             }
19549         }
19550     }
19551
19552     /**
19553      * Ask a given process to GC right now.
19554      */
19555     final void performAppGcLocked(ProcessRecord app) {
19556         try {
19557             app.lastRequestedGc = SystemClock.uptimeMillis();
19558             if (app.thread != null) {
19559                 if (app.reportLowMemory) {
19560                     app.reportLowMemory = false;
19561                     app.thread.scheduleLowMemory();
19562                 } else {
19563                     app.thread.processInBackground();
19564                 }
19565             }
19566         } catch (Exception e) {
19567             // whatever.
19568         }
19569     }
19570
19571     /**
19572      * Returns true if things are idle enough to perform GCs.
19573      */
19574     private final boolean canGcNowLocked() {
19575         boolean processingBroadcasts = false;
19576         for (BroadcastQueue q : mBroadcastQueues) {
19577             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19578                 processingBroadcasts = true;
19579             }
19580         }
19581         return !processingBroadcasts
19582                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19583     }
19584
19585     /**
19586      * Perform GCs on all processes that are waiting for it, but only
19587      * if things are idle.
19588      */
19589     final void performAppGcsLocked() {
19590         final int N = mProcessesToGc.size();
19591         if (N <= 0) {
19592             return;
19593         }
19594         if (canGcNowLocked()) {
19595             while (mProcessesToGc.size() > 0) {
19596                 ProcessRecord proc = mProcessesToGc.remove(0);
19597                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19598                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19599                             <= SystemClock.uptimeMillis()) {
19600                         // To avoid spamming the system, we will GC processes one
19601                         // at a time, waiting a few seconds between each.
19602                         performAppGcLocked(proc);
19603                         scheduleAppGcsLocked();
19604                         return;
19605                     } else {
19606                         // It hasn't been long enough since we last GCed this
19607                         // process...  put it in the list to wait for its time.
19608                         addProcessToGcListLocked(proc);
19609                         break;
19610                     }
19611                 }
19612             }
19613
19614             scheduleAppGcsLocked();
19615         }
19616     }
19617
19618     /**
19619      * If all looks good, perform GCs on all processes waiting for them.
19620      */
19621     final void performAppGcsIfAppropriateLocked() {
19622         if (canGcNowLocked()) {
19623             performAppGcsLocked();
19624             return;
19625         }
19626         // Still not idle, wait some more.
19627         scheduleAppGcsLocked();
19628     }
19629
19630     /**
19631      * Schedule the execution of all pending app GCs.
19632      */
19633     final void scheduleAppGcsLocked() {
19634         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19635
19636         if (mProcessesToGc.size() > 0) {
19637             // Schedule a GC for the time to the next process.
19638             ProcessRecord proc = mProcessesToGc.get(0);
19639             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19640
19641             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19642             long now = SystemClock.uptimeMillis();
19643             if (when < (now+GC_TIMEOUT)) {
19644                 when = now + GC_TIMEOUT;
19645             }
19646             mHandler.sendMessageAtTime(msg, when);
19647         }
19648     }
19649
19650     /**
19651      * Add a process to the array of processes waiting to be GCed.  Keeps the
19652      * list in sorted order by the last GC time.  The process can't already be
19653      * on the list.
19654      */
19655     final void addProcessToGcListLocked(ProcessRecord proc) {
19656         boolean added = false;
19657         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19658             if (mProcessesToGc.get(i).lastRequestedGc <
19659                     proc.lastRequestedGc) {
19660                 added = true;
19661                 mProcessesToGc.add(i+1, proc);
19662                 break;
19663             }
19664         }
19665         if (!added) {
19666             mProcessesToGc.add(0, proc);
19667         }
19668     }
19669
19670     /**
19671      * Set up to ask a process to GC itself.  This will either do it
19672      * immediately, or put it on the list of processes to gc the next
19673      * time things are idle.
19674      */
19675     final void scheduleAppGcLocked(ProcessRecord app) {
19676         long now = SystemClock.uptimeMillis();
19677         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19678             return;
19679         }
19680         if (!mProcessesToGc.contains(app)) {
19681             addProcessToGcListLocked(app);
19682             scheduleAppGcsLocked();
19683         }
19684     }
19685
19686     final void checkExcessivePowerUsageLocked(boolean doKills) {
19687         updateCpuStatsNow();
19688
19689         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19690         boolean doWakeKills = doKills;
19691         boolean doCpuKills = doKills;
19692         if (mLastPowerCheckRealtime == 0) {
19693             doWakeKills = false;
19694         }
19695         if (mLastPowerCheckUptime == 0) {
19696             doCpuKills = false;
19697         }
19698         if (stats.isScreenOn()) {
19699             doWakeKills = false;
19700         }
19701         final long curRealtime = SystemClock.elapsedRealtime();
19702         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19703         final long curUptime = SystemClock.uptimeMillis();
19704         final long uptimeSince = curUptime - mLastPowerCheckUptime;
19705         mLastPowerCheckRealtime = curRealtime;
19706         mLastPowerCheckUptime = curUptime;
19707         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19708             doWakeKills = false;
19709         }
19710         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19711             doCpuKills = false;
19712         }
19713         int i = mLruProcesses.size();
19714         while (i > 0) {
19715             i--;
19716             ProcessRecord app = mLruProcesses.get(i);
19717             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19718                 long wtime;
19719                 synchronized (stats) {
19720                     wtime = stats.getProcessWakeTime(app.info.uid,
19721                             app.pid, curRealtime);
19722                 }
19723                 long wtimeUsed = wtime - app.lastWakeTime;
19724                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19725                 if (DEBUG_POWER) {
19726                     StringBuilder sb = new StringBuilder(128);
19727                     sb.append("Wake for ");
19728                     app.toShortString(sb);
19729                     sb.append(": over ");
19730                     TimeUtils.formatDuration(realtimeSince, sb);
19731                     sb.append(" used ");
19732                     TimeUtils.formatDuration(wtimeUsed, sb);
19733                     sb.append(" (");
19734                     sb.append((wtimeUsed*100)/realtimeSince);
19735                     sb.append("%)");
19736                     Slog.i(TAG_POWER, sb.toString());
19737                     sb.setLength(0);
19738                     sb.append("CPU for ");
19739                     app.toShortString(sb);
19740                     sb.append(": over ");
19741                     TimeUtils.formatDuration(uptimeSince, sb);
19742                     sb.append(" used ");
19743                     TimeUtils.formatDuration(cputimeUsed, sb);
19744                     sb.append(" (");
19745                     sb.append((cputimeUsed*100)/uptimeSince);
19746                     sb.append("%)");
19747                     Slog.i(TAG_POWER, sb.toString());
19748                 }
19749                 // If a process has held a wake lock for more
19750                 // than 50% of the time during this period,
19751                 // that sounds bad.  Kill!
19752                 if (doWakeKills && realtimeSince > 0
19753                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
19754                     synchronized (stats) {
19755                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19756                                 realtimeSince, wtimeUsed);
19757                     }
19758                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19759                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19760                 } else if (doCpuKills && uptimeSince > 0
19761                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
19762                     synchronized (stats) {
19763                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19764                                 uptimeSince, cputimeUsed);
19765                     }
19766                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19767                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19768                 } else {
19769                     app.lastWakeTime = wtime;
19770                     app.lastCpuTime = app.curCpuTime;
19771                 }
19772             }
19773         }
19774     }
19775
19776     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19777             long nowElapsed) {
19778         boolean success = true;
19779
19780         if (app.curRawAdj != app.setRawAdj) {
19781             app.setRawAdj = app.curRawAdj;
19782         }
19783
19784         int changes = 0;
19785
19786         if (app.curAdj != app.setAdj) {
19787             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19788             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19789                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19790                     + app.adjType);
19791             app.setAdj = app.curAdj;
19792         }
19793
19794         if (app.setSchedGroup != app.curSchedGroup) {
19795             app.setSchedGroup = app.curSchedGroup;
19796             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19797                     "Setting sched group of " + app.processName
19798                     + " to " + app.curSchedGroup);
19799             if (app.waitingToKill != null && app.curReceiver == null
19800                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19801                 app.kill(app.waitingToKill, true);
19802                 success = false;
19803             } else {
19804                 int processGroup;
19805                 switch (app.curSchedGroup) {
19806                     case ProcessList.SCHED_GROUP_BACKGROUND:
19807                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19808                         break;
19809                     case ProcessList.SCHED_GROUP_TOP_APP:
19810                         processGroup = Process.THREAD_GROUP_TOP_APP;
19811                         break;
19812                     default:
19813                         processGroup = Process.THREAD_GROUP_DEFAULT;
19814                         break;
19815                 }
19816                 if (true) {
19817                     long oldId = Binder.clearCallingIdentity();
19818                     try {
19819                         Process.setProcessGroup(app.pid, processGroup);
19820                     } catch (Exception e) {
19821                         Slog.w(TAG, "Failed setting process group of " + app.pid
19822                                 + " to " + app.curSchedGroup);
19823                         e.printStackTrace();
19824                     } finally {
19825                         Binder.restoreCallingIdentity(oldId);
19826                     }
19827                 } else {
19828                     if (app.thread != null) {
19829                         try {
19830                             app.thread.setSchedulingGroup(processGroup);
19831                         } catch (RemoteException e) {
19832                         }
19833                     }
19834                 }
19835             }
19836         }
19837         if (app.repForegroundActivities != app.foregroundActivities) {
19838             app.repForegroundActivities = app.foregroundActivities;
19839             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19840         }
19841         if (app.repProcState != app.curProcState) {
19842             app.repProcState = app.curProcState;
19843             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19844             if (app.thread != null) {
19845                 try {
19846                     if (false) {
19847                         //RuntimeException h = new RuntimeException("here");
19848                         Slog.i(TAG, "Sending new process state " + app.repProcState
19849                                 + " to " + app /*, h*/);
19850                     }
19851                     app.thread.setProcessState(app.repProcState);
19852                 } catch (RemoteException e) {
19853                 }
19854             }
19855         }
19856         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19857                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19858             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19859                 // Experimental code to more aggressively collect pss while
19860                 // running test...  the problem is that this tends to collect
19861                 // the data right when a process is transitioning between process
19862                 // states, which well tend to give noisy data.
19863                 long start = SystemClock.uptimeMillis();
19864                 long pss = Debug.getPss(app.pid, mTmpLong, null);
19865                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19866                 mPendingPssProcesses.remove(app);
19867                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19868                         + " to " + app.curProcState + ": "
19869                         + (SystemClock.uptimeMillis()-start) + "ms");
19870             }
19871             app.lastStateTime = now;
19872             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19873                     mTestPssMode, isSleeping(), now);
19874             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19875                     + ProcessList.makeProcStateString(app.setProcState) + " to "
19876                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19877                     + (app.nextPssTime-now) + ": " + app);
19878         } else {
19879             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19880                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19881                     mTestPssMode)))) {
19882                 requestPssLocked(app, app.setProcState);
19883                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19884                         mTestPssMode, isSleeping(), now);
19885             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19886                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19887         }
19888         if (app.setProcState != app.curProcState) {
19889             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19890                     "Proc state change of " + app.processName
19891                             + " to " + app.curProcState);
19892             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19893             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19894             if (setImportant && !curImportant) {
19895                 // This app is no longer something we consider important enough to allow to
19896                 // use arbitrary amounts of battery power.  Note
19897                 // its current wake lock time to later know to kill it if
19898                 // it is not behaving well.
19899                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19900                 synchronized (stats) {
19901                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19902                             app.pid, nowElapsed);
19903                 }
19904                 app.lastCpuTime = app.curCpuTime;
19905
19906             }
19907             // Inform UsageStats of important process state change
19908             // Must be called before updating setProcState
19909             maybeUpdateUsageStatsLocked(app, nowElapsed);
19910
19911             app.setProcState = app.curProcState;
19912             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19913                 app.notCachedSinceIdle = false;
19914             }
19915             if (!doingAll) {
19916                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19917             } else {
19918                 app.procStateChanged = true;
19919             }
19920         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19921                 > USAGE_STATS_INTERACTION_INTERVAL) {
19922             // For apps that sit around for a long time in the interactive state, we need
19923             // to report this at least once a day so they don't go idle.
19924             maybeUpdateUsageStatsLocked(app, nowElapsed);
19925         }
19926
19927         if (changes != 0) {
19928             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19929                     "Changes in " + app + ": " + changes);
19930             int i = mPendingProcessChanges.size()-1;
19931             ProcessChangeItem item = null;
19932             while (i >= 0) {
19933                 item = mPendingProcessChanges.get(i);
19934                 if (item.pid == app.pid) {
19935                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19936                             "Re-using existing item: " + item);
19937                     break;
19938                 }
19939                 i--;
19940             }
19941             if (i < 0) {
19942                 // No existing item in pending changes; need a new one.
19943                 final int NA = mAvailProcessChanges.size();
19944                 if (NA > 0) {
19945                     item = mAvailProcessChanges.remove(NA-1);
19946                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19947                             "Retrieving available item: " + item);
19948                 } else {
19949                     item = new ProcessChangeItem();
19950                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19951                             "Allocating new item: " + item);
19952                 }
19953                 item.changes = 0;
19954                 item.pid = app.pid;
19955                 item.uid = app.info.uid;
19956                 if (mPendingProcessChanges.size() == 0) {
19957                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19958                             "*** Enqueueing dispatch processes changed!");
19959                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19960                 }
19961                 mPendingProcessChanges.add(item);
19962             }
19963             item.changes |= changes;
19964             item.processState = app.repProcState;
19965             item.foregroundActivities = app.repForegroundActivities;
19966             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19967                     "Item " + Integer.toHexString(System.identityHashCode(item))
19968                     + " " + app.toShortString() + ": changes=" + item.changes
19969                     + " procState=" + item.processState
19970                     + " foreground=" + item.foregroundActivities
19971                     + " type=" + app.adjType + " source=" + app.adjSource
19972                     + " target=" + app.adjTarget);
19973         }
19974
19975         return success;
19976     }
19977
19978     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19979         final UidRecord.ChangeItem pendingChange;
19980         if (uidRec == null || uidRec.pendingChange == null) {
19981             if (mPendingUidChanges.size() == 0) {
19982                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19983                         "*** Enqueueing dispatch uid changed!");
19984                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19985             }
19986             final int NA = mAvailUidChanges.size();
19987             if (NA > 0) {
19988                 pendingChange = mAvailUidChanges.remove(NA-1);
19989                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19990                         "Retrieving available item: " + pendingChange);
19991             } else {
19992                 pendingChange = new UidRecord.ChangeItem();
19993                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19994                         "Allocating new item: " + pendingChange);
19995             }
19996             if (uidRec != null) {
19997                 uidRec.pendingChange = pendingChange;
19998                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19999                     // If this uid is going away, and we haven't yet reported it is gone,
20000                     // then do so now.
20001                     change = UidRecord.CHANGE_GONE_IDLE;
20002                 }
20003             } else if (uid < 0) {
20004                 throw new IllegalArgumentException("No UidRecord or uid");
20005             }
20006             pendingChange.uidRecord = uidRec;
20007             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20008             mPendingUidChanges.add(pendingChange);
20009         } else {
20010             pendingChange = uidRec.pendingChange;
20011             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20012                 change = UidRecord.CHANGE_GONE_IDLE;
20013             }
20014         }
20015         pendingChange.change = change;
20016         pendingChange.processState = uidRec != null
20017                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20018     }
20019
20020     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20021             String authority) {
20022         if (app == null) return;
20023         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20024             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20025             if (userState == null) return;
20026             final long now = SystemClock.elapsedRealtime();
20027             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20028             if (lastReported == null || lastReported < now - 60 * 1000L) {
20029                 mUsageStatsService.reportContentProviderUsage(
20030                         authority, providerPkgName, app.userId);
20031                 userState.mProviderLastReportedFg.put(authority, now);
20032             }
20033         }
20034     }
20035
20036     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20037         if (DEBUG_USAGE_STATS) {
20038             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20039                     + "] state changes: old = " + app.setProcState + ", new = "
20040                     + app.curProcState);
20041         }
20042         if (mUsageStatsService == null) {
20043             return;
20044         }
20045         boolean isInteraction;
20046         // To avoid some abuse patterns, we are going to be careful about what we consider
20047         // to be an app interaction.  Being the top activity doesn't count while the display
20048         // is sleeping, nor do short foreground services.
20049         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20050             isInteraction = true;
20051             app.fgInteractionTime = 0;
20052         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20053             if (app.fgInteractionTime == 0) {
20054                 app.fgInteractionTime = nowElapsed;
20055                 isInteraction = false;
20056             } else {
20057                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20058             }
20059         } else {
20060             isInteraction = app.curProcState
20061                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20062             app.fgInteractionTime = 0;
20063         }
20064         if (isInteraction && (!app.reportedInteraction
20065                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20066             app.interactionEventTime = nowElapsed;
20067             String[] packages = app.getPackageList();
20068             if (packages != null) {
20069                 for (int i = 0; i < packages.length; i++) {
20070                     mUsageStatsService.reportEvent(packages[i], app.userId,
20071                             UsageEvents.Event.SYSTEM_INTERACTION);
20072                 }
20073             }
20074         }
20075         app.reportedInteraction = isInteraction;
20076         if (!isInteraction) {
20077             app.interactionEventTime = 0;
20078         }
20079     }
20080
20081     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20082         if (proc.thread != null) {
20083             if (proc.baseProcessTracker != null) {
20084                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20085             }
20086         }
20087     }
20088
20089     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20090             ProcessRecord TOP_APP, boolean doingAll, long now) {
20091         if (app.thread == null) {
20092             return false;
20093         }
20094
20095         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20096
20097         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20098     }
20099
20100     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20101             boolean oomAdj) {
20102         if (isForeground != proc.foregroundServices) {
20103             proc.foregroundServices = isForeground;
20104             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20105                     proc.info.uid);
20106             if (isForeground) {
20107                 if (curProcs == null) {
20108                     curProcs = new ArrayList<ProcessRecord>();
20109                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20110                 }
20111                 if (!curProcs.contains(proc)) {
20112                     curProcs.add(proc);
20113                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20114                             proc.info.packageName, proc.info.uid);
20115                 }
20116             } else {
20117                 if (curProcs != null) {
20118                     if (curProcs.remove(proc)) {
20119                         mBatteryStatsService.noteEvent(
20120                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20121                                 proc.info.packageName, proc.info.uid);
20122                         if (curProcs.size() <= 0) {
20123                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20124                         }
20125                     }
20126                 }
20127             }
20128             if (oomAdj) {
20129                 updateOomAdjLocked();
20130             }
20131         }
20132     }
20133
20134     private final ActivityRecord resumedAppLocked() {
20135         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20136         String pkg;
20137         int uid;
20138         if (act != null) {
20139             pkg = act.packageName;
20140             uid = act.info.applicationInfo.uid;
20141         } else {
20142             pkg = null;
20143             uid = -1;
20144         }
20145         // Has the UID or resumed package name changed?
20146         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20147                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20148             if (mCurResumedPackage != null) {
20149                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20150                         mCurResumedPackage, mCurResumedUid);
20151             }
20152             mCurResumedPackage = pkg;
20153             mCurResumedUid = uid;
20154             if (mCurResumedPackage != null) {
20155                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20156                         mCurResumedPackage, mCurResumedUid);
20157             }
20158         }
20159         return act;
20160     }
20161
20162     final boolean updateOomAdjLocked(ProcessRecord app) {
20163         final ActivityRecord TOP_ACT = resumedAppLocked();
20164         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20165         final boolean wasCached = app.cached;
20166
20167         mAdjSeq++;
20168
20169         // This is the desired cached adjusment we want to tell it to use.
20170         // If our app is currently cached, we know it, and that is it.  Otherwise,
20171         // we don't know it yet, and it needs to now be cached we will then
20172         // need to do a complete oom adj.
20173         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20174                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20175         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20176                 SystemClock.uptimeMillis());
20177         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20178             // Changed to/from cached state, so apps after it in the LRU
20179             // list may also be changed.
20180             updateOomAdjLocked();
20181         }
20182         return success;
20183     }
20184
20185     final void updateOomAdjLocked() {
20186         final ActivityRecord TOP_ACT = resumedAppLocked();
20187         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20188         final long now = SystemClock.uptimeMillis();
20189         final long nowElapsed = SystemClock.elapsedRealtime();
20190         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20191         final int N = mLruProcesses.size();
20192
20193         if (false) {
20194             RuntimeException e = new RuntimeException();
20195             e.fillInStackTrace();
20196             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20197         }
20198
20199         // Reset state in all uid records.
20200         for (int i=mActiveUids.size()-1; i>=0; i--) {
20201             final UidRecord uidRec = mActiveUids.valueAt(i);
20202             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20203                     "Starting update of " + uidRec);
20204             uidRec.reset();
20205         }
20206
20207         mStackSupervisor.rankTaskLayersIfNeeded();
20208
20209         mAdjSeq++;
20210         mNewNumServiceProcs = 0;
20211         mNewNumAServiceProcs = 0;
20212
20213         final int emptyProcessLimit;
20214         final int cachedProcessLimit;
20215         if (mProcessLimit <= 0) {
20216             emptyProcessLimit = cachedProcessLimit = 0;
20217         } else if (mProcessLimit == 1) {
20218             emptyProcessLimit = 1;
20219             cachedProcessLimit = 0;
20220         } else {
20221             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20222             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20223         }
20224
20225         // Let's determine how many processes we have running vs.
20226         // how many slots we have for background processes; we may want
20227         // to put multiple processes in a slot of there are enough of
20228         // them.
20229         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20230                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20231         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20232         if (numEmptyProcs > cachedProcessLimit) {
20233             // If there are more empty processes than our limit on cached
20234             // processes, then use the cached process limit for the factor.
20235             // This ensures that the really old empty processes get pushed
20236             // down to the bottom, so if we are running low on memory we will
20237             // have a better chance at keeping around more cached processes
20238             // instead of a gazillion empty processes.
20239             numEmptyProcs = cachedProcessLimit;
20240         }
20241         int emptyFactor = numEmptyProcs/numSlots;
20242         if (emptyFactor < 1) emptyFactor = 1;
20243         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20244         if (cachedFactor < 1) cachedFactor = 1;
20245         int stepCached = 0;
20246         int stepEmpty = 0;
20247         int numCached = 0;
20248         int numEmpty = 0;
20249         int numTrimming = 0;
20250
20251         mNumNonCachedProcs = 0;
20252         mNumCachedHiddenProcs = 0;
20253
20254         // First update the OOM adjustment for each of the
20255         // application processes based on their current state.
20256         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20257         int nextCachedAdj = curCachedAdj+1;
20258         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20259         int nextEmptyAdj = curEmptyAdj+2;
20260         for (int i=N-1; i>=0; i--) {
20261             ProcessRecord app = mLruProcesses.get(i);
20262             if (!app.killedByAm && app.thread != null) {
20263                 app.procStateChanged = false;
20264                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20265
20266                 // If we haven't yet assigned the final cached adj
20267                 // to the process, do that now.
20268                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20269                     switch (app.curProcState) {
20270                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20271                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20272                             // This process is a cached process holding activities...
20273                             // assign it the next cached value for that type, and then
20274                             // step that cached level.
20275                             app.curRawAdj = curCachedAdj;
20276                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20277                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20278                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20279                                     + ")");
20280                             if (curCachedAdj != nextCachedAdj) {
20281                                 stepCached++;
20282                                 if (stepCached >= cachedFactor) {
20283                                     stepCached = 0;
20284                                     curCachedAdj = nextCachedAdj;
20285                                     nextCachedAdj += 2;
20286                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20287                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20288                                     }
20289                                 }
20290                             }
20291                             break;
20292                         default:
20293                             // For everything else, assign next empty cached process
20294                             // level and bump that up.  Note that this means that
20295                             // long-running services that have dropped down to the
20296                             // cached level will be treated as empty (since their process
20297                             // state is still as a service), which is what we want.
20298                             app.curRawAdj = curEmptyAdj;
20299                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20300                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20301                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20302                                     + ")");
20303                             if (curEmptyAdj != nextEmptyAdj) {
20304                                 stepEmpty++;
20305                                 if (stepEmpty >= emptyFactor) {
20306                                     stepEmpty = 0;
20307                                     curEmptyAdj = nextEmptyAdj;
20308                                     nextEmptyAdj += 2;
20309                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20310                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20311                                     }
20312                                 }
20313                             }
20314                             break;
20315                     }
20316                 }
20317
20318                 applyOomAdjLocked(app, true, now, nowElapsed);
20319
20320                 // Count the number of process types.
20321                 switch (app.curProcState) {
20322                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20323                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20324                         mNumCachedHiddenProcs++;
20325                         numCached++;
20326                         if (numCached > cachedProcessLimit) {
20327                             app.kill("cached #" + numCached, true);
20328                         }
20329                         break;
20330                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20331                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20332                                 && app.lastActivityTime < oldTime) {
20333                             app.kill("empty for "
20334                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20335                                     / 1000) + "s", true);
20336                         } else {
20337                             numEmpty++;
20338                             if (numEmpty > emptyProcessLimit) {
20339                                 app.kill("empty #" + numEmpty, true);
20340                             }
20341                         }
20342                         break;
20343                     default:
20344                         mNumNonCachedProcs++;
20345                         break;
20346                 }
20347
20348                 if (app.isolated && app.services.size() <= 0) {
20349                     // If this is an isolated process, and there are no
20350                     // services running in it, then the process is no longer
20351                     // needed.  We agressively kill these because we can by
20352                     // definition not re-use the same process again, and it is
20353                     // good to avoid having whatever code was running in them
20354                     // left sitting around after no longer needed.
20355                     app.kill("isolated not needed", true);
20356                 } else {
20357                     // Keeping this process, update its uid.
20358                     final UidRecord uidRec = app.uidRecord;
20359                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
20360                         uidRec.curProcState = app.curProcState;
20361                     }
20362                 }
20363
20364                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20365                         && !app.killedByAm) {
20366                     numTrimming++;
20367                 }
20368             }
20369         }
20370
20371         mNumServiceProcs = mNewNumServiceProcs;
20372
20373         // Now determine the memory trimming level of background processes.
20374         // Unfortunately we need to start at the back of the list to do this
20375         // properly.  We only do this if the number of background apps we
20376         // are managing to keep around is less than half the maximum we desire;
20377         // if we are keeping a good number around, we'll let them use whatever
20378         // memory they want.
20379         final int numCachedAndEmpty = numCached + numEmpty;
20380         int memFactor;
20381         if (numCached <= ProcessList.TRIM_CACHED_APPS
20382                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20383             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20384                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20385             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20386                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20387             } else {
20388                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20389             }
20390         } else {
20391             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20392         }
20393         // We always allow the memory level to go up (better).  We only allow it to go
20394         // down if we are in a state where that is allowed, *and* the total number of processes
20395         // has gone down since last time.
20396         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20397                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20398                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20399         if (memFactor > mLastMemoryLevel) {
20400             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20401                 memFactor = mLastMemoryLevel;
20402                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20403             }
20404         }
20405         if (memFactor != mLastMemoryLevel) {
20406             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20407         }
20408         mLastMemoryLevel = memFactor;
20409         mLastNumProcesses = mLruProcesses.size();
20410         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20411         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20412         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20413             if (mLowRamStartTime == 0) {
20414                 mLowRamStartTime = now;
20415             }
20416             int step = 0;
20417             int fgTrimLevel;
20418             switch (memFactor) {
20419                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20420                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20421                     break;
20422                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20423                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20424                     break;
20425                 default:
20426                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20427                     break;
20428             }
20429             int factor = numTrimming/3;
20430             int minFactor = 2;
20431             if (mHomeProcess != null) minFactor++;
20432             if (mPreviousProcess != null) minFactor++;
20433             if (factor < minFactor) factor = minFactor;
20434             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20435             for (int i=N-1; i>=0; i--) {
20436                 ProcessRecord app = mLruProcesses.get(i);
20437                 if (allChanged || app.procStateChanged) {
20438                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20439                     app.procStateChanged = false;
20440                 }
20441                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20442                         && !app.killedByAm) {
20443                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
20444                         try {
20445                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20446                                     "Trimming memory of " + app.processName + " to " + curLevel);
20447                             app.thread.scheduleTrimMemory(curLevel);
20448                         } catch (RemoteException e) {
20449                         }
20450                         if (false) {
20451                             // For now we won't do this; our memory trimming seems
20452                             // to be good enough at this point that destroying
20453                             // activities causes more harm than good.
20454                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20455                                     && app != mHomeProcess && app != mPreviousProcess) {
20456                                 // Need to do this on its own message because the stack may not
20457                                 // be in a consistent state at this point.
20458                                 // For these apps we will also finish their activities
20459                                 // to help them free memory.
20460                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20461                             }
20462                         }
20463                     }
20464                     app.trimMemoryLevel = curLevel;
20465                     step++;
20466                     if (step >= factor) {
20467                         step = 0;
20468                         switch (curLevel) {
20469                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20470                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20471                                 break;
20472                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20473                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20474                                 break;
20475                         }
20476                     }
20477                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20478                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20479                             && app.thread != null) {
20480                         try {
20481                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20482                                     "Trimming memory of heavy-weight " + app.processName
20483                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20484                             app.thread.scheduleTrimMemory(
20485                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20486                         } catch (RemoteException e) {
20487                         }
20488                     }
20489                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20490                 } else {
20491                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20492                             || app.systemNoUi) && app.pendingUiClean) {
20493                         // If this application is now in the background and it
20494                         // had done UI, then give it the special trim level to
20495                         // have it free UI resources.
20496                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20497                         if (app.trimMemoryLevel < level && app.thread != null) {
20498                             try {
20499                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20500                                         "Trimming memory of bg-ui " + app.processName
20501                                         + " to " + level);
20502                                 app.thread.scheduleTrimMemory(level);
20503                             } catch (RemoteException e) {
20504                             }
20505                         }
20506                         app.pendingUiClean = false;
20507                     }
20508                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20509                         try {
20510                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20511                                     "Trimming memory of fg " + app.processName
20512                                     + " to " + fgTrimLevel);
20513                             app.thread.scheduleTrimMemory(fgTrimLevel);
20514                         } catch (RemoteException e) {
20515                         }
20516                     }
20517                     app.trimMemoryLevel = fgTrimLevel;
20518                 }
20519             }
20520         } else {
20521             if (mLowRamStartTime != 0) {
20522                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20523                 mLowRamStartTime = 0;
20524             }
20525             for (int i=N-1; i>=0; i--) {
20526                 ProcessRecord app = mLruProcesses.get(i);
20527                 if (allChanged || app.procStateChanged) {
20528                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20529                     app.procStateChanged = false;
20530                 }
20531                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20532                         || app.systemNoUi) && app.pendingUiClean) {
20533                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20534                             && app.thread != null) {
20535                         try {
20536                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20537                                     "Trimming memory of ui hidden " + app.processName
20538                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20539                             app.thread.scheduleTrimMemory(
20540                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20541                         } catch (RemoteException e) {
20542                         }
20543                     }
20544                     app.pendingUiClean = false;
20545                 }
20546                 app.trimMemoryLevel = 0;
20547             }
20548         }
20549
20550         if (mAlwaysFinishActivities) {
20551             // Need to do this on its own message because the stack may not
20552             // be in a consistent state at this point.
20553             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20554         }
20555
20556         if (allChanged) {
20557             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20558         }
20559
20560         // Update from any uid changes.
20561         for (int i=mActiveUids.size()-1; i>=0; i--) {
20562             final UidRecord uidRec = mActiveUids.valueAt(i);
20563             int uidChange = UidRecord.CHANGE_PROCSTATE;
20564             if (uidRec.setProcState != uidRec.curProcState) {
20565                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20566                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20567                         + " to " + uidRec.curProcState);
20568                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20569                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20570                         uidRec.lastBackgroundTime = nowElapsed;
20571                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20572                             // Note: the background settle time is in elapsed realtime, while
20573                             // the handler time base is uptime.  All this means is that we may
20574                             // stop background uids later than we had intended, but that only
20575                             // happens because the device was sleeping so we are okay anyway.
20576                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20577                         }
20578                     }
20579                 } else {
20580                     if (uidRec.idle) {
20581                         uidChange = UidRecord.CHANGE_ACTIVE;
20582                         uidRec.idle = false;
20583                     }
20584                     uidRec.lastBackgroundTime = 0;
20585                 }
20586                 uidRec.setProcState = uidRec.curProcState;
20587                 enqueueUidChangeLocked(uidRec, -1, uidChange);
20588                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20589             }
20590         }
20591
20592         if (mProcessStats.shouldWriteNowLocked(now)) {
20593             mHandler.post(new Runnable() {
20594                 @Override public void run() {
20595                     synchronized (ActivityManagerService.this) {
20596                         mProcessStats.writeStateAsyncLocked();
20597                     }
20598                 }
20599             });
20600         }
20601
20602         if (DEBUG_OOM_ADJ) {
20603             final long duration = SystemClock.uptimeMillis() - now;
20604             if (false) {
20605                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20606                         new RuntimeException("here").fillInStackTrace());
20607             } else {
20608                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20609             }
20610         }
20611     }
20612
20613     final void idleUids() {
20614         synchronized (this) {
20615             final long nowElapsed = SystemClock.elapsedRealtime();
20616             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20617             long nextTime = 0;
20618             for (int i=mActiveUids.size()-1; i>=0; i--) {
20619                 final UidRecord uidRec = mActiveUids.valueAt(i);
20620                 final long bgTime = uidRec.lastBackgroundTime;
20621                 if (bgTime > 0 && !uidRec.idle) {
20622                     if (bgTime <= maxBgTime) {
20623                         uidRec.idle = true;
20624                         doStopUidLocked(uidRec.uid, uidRec);
20625                     } else {
20626                         if (nextTime == 0 || nextTime > bgTime) {
20627                             nextTime = bgTime;
20628                         }
20629                     }
20630                 }
20631             }
20632             if (nextTime > 0) {
20633                 mHandler.removeMessages(IDLE_UIDS_MSG);
20634                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20635                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20636             }
20637         }
20638     }
20639
20640     final void runInBackgroundDisabled(int uid) {
20641         synchronized (this) {
20642             UidRecord uidRec = mActiveUids.get(uid);
20643             if (uidRec != null) {
20644                 // This uid is actually running...  should it be considered background now?
20645                 if (uidRec.idle) {
20646                     doStopUidLocked(uidRec.uid, uidRec);
20647                 }
20648             } else {
20649                 // This uid isn't actually running...  still send a report about it being "stopped".
20650                 doStopUidLocked(uid, null);
20651             }
20652         }
20653     }
20654
20655     final void doStopUidLocked(int uid, final UidRecord uidRec) {
20656         mServices.stopInBackgroundLocked(uid);
20657         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20658     }
20659
20660     final void trimApplications() {
20661         synchronized (this) {
20662             int i;
20663
20664             // First remove any unused application processes whose package
20665             // has been removed.
20666             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20667                 final ProcessRecord app = mRemovedProcesses.get(i);
20668                 if (app.activities.size() == 0
20669                         && app.curReceiver == null && app.services.size() == 0) {
20670                     Slog.i(
20671                         TAG, "Exiting empty application process "
20672                         + app.toShortString() + " ("
20673                         + (app.thread != null ? app.thread.asBinder() : null)
20674                         + ")\n");
20675                     if (app.pid > 0 && app.pid != MY_PID) {
20676                         app.kill("empty", false);
20677                     } else {
20678                         try {
20679                             app.thread.scheduleExit();
20680                         } catch (Exception e) {
20681                             // Ignore exceptions.
20682                         }
20683                     }
20684                     cleanUpApplicationRecordLocked(app, false, true, -1);
20685                     mRemovedProcesses.remove(i);
20686
20687                     if (app.persistent) {
20688                         addAppLocked(app.info, false, null /* ABI override */);
20689                     }
20690                 }
20691             }
20692
20693             // Now update the oom adj for all processes.
20694             updateOomAdjLocked();
20695         }
20696     }
20697
20698     /** This method sends the specified signal to each of the persistent apps */
20699     public void signalPersistentProcesses(int sig) throws RemoteException {
20700         if (sig != Process.SIGNAL_USR1) {
20701             throw new SecurityException("Only SIGNAL_USR1 is allowed");
20702         }
20703
20704         synchronized (this) {
20705             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20706                     != PackageManager.PERMISSION_GRANTED) {
20707                 throw new SecurityException("Requires permission "
20708                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20709             }
20710
20711             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20712                 ProcessRecord r = mLruProcesses.get(i);
20713                 if (r.thread != null && r.persistent) {
20714                     Process.sendSignal(r.pid, sig);
20715                 }
20716             }
20717         }
20718     }
20719
20720     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20721         if (proc == null || proc == mProfileProc) {
20722             proc = mProfileProc;
20723             profileType = mProfileType;
20724             clearProfilerLocked();
20725         }
20726         if (proc == null) {
20727             return;
20728         }
20729         try {
20730             proc.thread.profilerControl(false, null, profileType);
20731         } catch (RemoteException e) {
20732             throw new IllegalStateException("Process disappeared");
20733         }
20734     }
20735
20736     private void clearProfilerLocked() {
20737         if (mProfileFd != null) {
20738             try {
20739                 mProfileFd.close();
20740             } catch (IOException e) {
20741             }
20742         }
20743         mProfileApp = null;
20744         mProfileProc = null;
20745         mProfileFile = null;
20746         mProfileType = 0;
20747         mAutoStopProfiler = false;
20748         mSamplingInterval = 0;
20749     }
20750
20751     public boolean profileControl(String process, int userId, boolean start,
20752             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20753
20754         try {
20755             synchronized (this) {
20756                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20757                 // its own permission.
20758                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20759                         != PackageManager.PERMISSION_GRANTED) {
20760                     throw new SecurityException("Requires permission "
20761                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20762                 }
20763
20764                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20765                     throw new IllegalArgumentException("null profile info or fd");
20766                 }
20767
20768                 ProcessRecord proc = null;
20769                 if (process != null) {
20770                     proc = findProcessLocked(process, userId, "profileControl");
20771                 }
20772
20773                 if (start && (proc == null || proc.thread == null)) {
20774                     throw new IllegalArgumentException("Unknown process: " + process);
20775                 }
20776
20777                 if (start) {
20778                     stopProfilerLocked(null, 0);
20779                     setProfileApp(proc.info, proc.processName, profilerInfo);
20780                     mProfileProc = proc;
20781                     mProfileType = profileType;
20782                     ParcelFileDescriptor fd = profilerInfo.profileFd;
20783                     try {
20784                         fd = fd.dup();
20785                     } catch (IOException e) {
20786                         fd = null;
20787                     }
20788                     profilerInfo.profileFd = fd;
20789                     proc.thread.profilerControl(start, profilerInfo, profileType);
20790                     fd = null;
20791                     mProfileFd = null;
20792                 } else {
20793                     stopProfilerLocked(proc, profileType);
20794                     if (profilerInfo != null && profilerInfo.profileFd != null) {
20795                         try {
20796                             profilerInfo.profileFd.close();
20797                         } catch (IOException e) {
20798                         }
20799                     }
20800                 }
20801
20802                 return true;
20803             }
20804         } catch (RemoteException e) {
20805             throw new IllegalStateException("Process disappeared");
20806         } finally {
20807             if (profilerInfo != null && profilerInfo.profileFd != null) {
20808                 try {
20809                     profilerInfo.profileFd.close();
20810                 } catch (IOException e) {
20811                 }
20812             }
20813         }
20814     }
20815
20816     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20817         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20818                 userId, true, ALLOW_FULL_ONLY, callName, null);
20819         ProcessRecord proc = null;
20820         try {
20821             int pid = Integer.parseInt(process);
20822             synchronized (mPidsSelfLocked) {
20823                 proc = mPidsSelfLocked.get(pid);
20824             }
20825         } catch (NumberFormatException e) {
20826         }
20827
20828         if (proc == null) {
20829             ArrayMap<String, SparseArray<ProcessRecord>> all
20830                     = mProcessNames.getMap();
20831             SparseArray<ProcessRecord> procs = all.get(process);
20832             if (procs != null && procs.size() > 0) {
20833                 proc = procs.valueAt(0);
20834                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20835                     for (int i=1; i<procs.size(); i++) {
20836                         ProcessRecord thisProc = procs.valueAt(i);
20837                         if (thisProc.userId == userId) {
20838                             proc = thisProc;
20839                             break;
20840                         }
20841                     }
20842                 }
20843             }
20844         }
20845
20846         return proc;
20847     }
20848
20849     public boolean dumpHeap(String process, int userId, boolean managed,
20850             String path, ParcelFileDescriptor fd) throws RemoteException {
20851
20852         try {
20853             synchronized (this) {
20854                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20855                 // its own permission (same as profileControl).
20856                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20857                         != PackageManager.PERMISSION_GRANTED) {
20858                     throw new SecurityException("Requires permission "
20859                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20860                 }
20861
20862                 if (fd == null) {
20863                     throw new IllegalArgumentException("null fd");
20864                 }
20865
20866                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20867                 if (proc == null || proc.thread == null) {
20868                     throw new IllegalArgumentException("Unknown process: " + process);
20869                 }
20870
20871                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20872                 if (!isDebuggable) {
20873                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20874                         throw new SecurityException("Process not debuggable: " + proc);
20875                     }
20876                 }
20877
20878                 proc.thread.dumpHeap(managed, path, fd);
20879                 fd = null;
20880                 return true;
20881             }
20882         } catch (RemoteException e) {
20883             throw new IllegalStateException("Process disappeared");
20884         } finally {
20885             if (fd != null) {
20886                 try {
20887                     fd.close();
20888                 } catch (IOException e) {
20889                 }
20890             }
20891         }
20892     }
20893
20894     @Override
20895     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20896             String reportPackage) {
20897         if (processName != null) {
20898             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20899                     "setDumpHeapDebugLimit()");
20900         } else {
20901             synchronized (mPidsSelfLocked) {
20902                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20903                 if (proc == null) {
20904                     throw new SecurityException("No process found for calling pid "
20905                             + Binder.getCallingPid());
20906                 }
20907                 if (!Build.IS_DEBUGGABLE
20908                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20909                     throw new SecurityException("Not running a debuggable build");
20910                 }
20911                 processName = proc.processName;
20912                 uid = proc.uid;
20913                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20914                     throw new SecurityException("Package " + reportPackage + " is not running in "
20915                             + proc);
20916                 }
20917             }
20918         }
20919         synchronized (this) {
20920             if (maxMemSize > 0) {
20921                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20922             } else {
20923                 if (uid != 0) {
20924                     mMemWatchProcesses.remove(processName, uid);
20925                 } else {
20926                     mMemWatchProcesses.getMap().remove(processName);
20927                 }
20928             }
20929         }
20930     }
20931
20932     @Override
20933     public void dumpHeapFinished(String path) {
20934         synchronized (this) {
20935             if (Binder.getCallingPid() != mMemWatchDumpPid) {
20936                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20937                         + " does not match last pid " + mMemWatchDumpPid);
20938                 return;
20939             }
20940             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20941                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20942                         + " does not match last path " + mMemWatchDumpFile);
20943                 return;
20944             }
20945             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20946             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20947         }
20948     }
20949
20950     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20951     public void monitor() {
20952         synchronized (this) { }
20953     }
20954
20955     void onCoreSettingsChange(Bundle settings) {
20956         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20957             ProcessRecord processRecord = mLruProcesses.get(i);
20958             try {
20959                 if (processRecord.thread != null) {
20960                     processRecord.thread.setCoreSettings(settings);
20961                 }
20962             } catch (RemoteException re) {
20963                 /* ignore */
20964             }
20965         }
20966     }
20967
20968     // Multi-user methods
20969
20970     /**
20971      * Start user, if its not already running, but don't bring it to foreground.
20972      */
20973     @Override
20974     public boolean startUserInBackground(final int userId) {
20975         return mUserController.startUser(userId, /* foreground */ false);
20976     }
20977
20978     @Override
20979     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20980         return mUserController.unlockUser(userId, token, secret, listener);
20981     }
20982
20983     @Override
20984     public boolean switchUser(final int targetUserId) {
20985         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20986         UserInfo currentUserInfo;
20987         UserInfo targetUserInfo;
20988         synchronized (this) {
20989             int currentUserId = mUserController.getCurrentUserIdLocked();
20990             currentUserInfo = mUserController.getUserInfo(currentUserId);
20991             targetUserInfo = mUserController.getUserInfo(targetUserId);
20992             if (targetUserInfo == null) {
20993                 Slog.w(TAG, "No user info for user #" + targetUserId);
20994                 return false;
20995             }
20996             if (!targetUserInfo.supportsSwitchTo()) {
20997                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20998                 return false;
20999             }
21000             if (targetUserInfo.isManagedProfile()) {
21001                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21002                 return false;
21003             }
21004             mUserController.setTargetUserIdLocked(targetUserId);
21005         }
21006         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21007         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21008         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21009         return true;
21010     }
21011
21012     void scheduleStartProfilesLocked() {
21013         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21014             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21015                     DateUtils.SECOND_IN_MILLIS);
21016         }
21017     }
21018
21019     @Override
21020     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21021         return mUserController.stopUser(userId, force, callback);
21022     }
21023
21024     @Override
21025     public UserInfo getCurrentUser() {
21026         return mUserController.getCurrentUser();
21027     }
21028
21029     @Override
21030     public boolean isUserRunning(int userId, int flags) {
21031         if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21032                 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21033             String msg = "Permission Denial: isUserRunning() from pid="
21034                     + Binder.getCallingPid()
21035                     + ", uid=" + Binder.getCallingUid()
21036                     + " requires " + INTERACT_ACROSS_USERS;
21037             Slog.w(TAG, msg);
21038             throw new SecurityException(msg);
21039         }
21040         synchronized (this) {
21041             return mUserController.isUserRunningLocked(userId, flags);
21042         }
21043     }
21044
21045     @Override
21046     public int[] getRunningUserIds() {
21047         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21048                 != PackageManager.PERMISSION_GRANTED) {
21049             String msg = "Permission Denial: isUserRunning() from pid="
21050                     + Binder.getCallingPid()
21051                     + ", uid=" + Binder.getCallingUid()
21052                     + " requires " + INTERACT_ACROSS_USERS;
21053             Slog.w(TAG, msg);
21054             throw new SecurityException(msg);
21055         }
21056         synchronized (this) {
21057             return mUserController.getStartedUserArrayLocked();
21058         }
21059     }
21060
21061     @Override
21062     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21063         mUserController.registerUserSwitchObserver(observer);
21064     }
21065
21066     @Override
21067     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21068         mUserController.unregisterUserSwitchObserver(observer);
21069     }
21070
21071     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21072         if (info == null) return null;
21073         ApplicationInfo newInfo = new ApplicationInfo(info);
21074         newInfo.initForUser(userId);
21075         return newInfo;
21076     }
21077
21078     public boolean isUserStopped(int userId) {
21079         synchronized (this) {
21080             return mUserController.getStartedUserStateLocked(userId) == null;
21081         }
21082     }
21083
21084     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21085         if (aInfo == null
21086                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21087             return aInfo;
21088         }
21089
21090         ActivityInfo info = new ActivityInfo(aInfo);
21091         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21092         return info;
21093     }
21094
21095     private boolean processSanityChecksLocked(ProcessRecord process) {
21096         if (process == null || process.thread == null) {
21097             return false;
21098         }
21099
21100         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21101         if (!isDebuggable) {
21102             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21103                 return false;
21104             }
21105         }
21106
21107         return true;
21108     }
21109
21110     public boolean startBinderTracking() throws RemoteException {
21111         synchronized (this) {
21112             mBinderTransactionTrackingEnabled = true;
21113             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21114             // permission (same as profileControl).
21115             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21116                     != PackageManager.PERMISSION_GRANTED) {
21117                 throw new SecurityException("Requires permission "
21118                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21119             }
21120
21121             for (int i = 0; i < mLruProcesses.size(); i++) {
21122                 ProcessRecord process = mLruProcesses.get(i);
21123                 if (!processSanityChecksLocked(process)) {
21124                     continue;
21125                 }
21126                 try {
21127                     process.thread.startBinderTracking();
21128                 } catch (RemoteException e) {
21129                     Log.v(TAG, "Process disappared");
21130                 }
21131             }
21132             return true;
21133         }
21134     }
21135
21136     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21137         try {
21138             synchronized (this) {
21139                 mBinderTransactionTrackingEnabled = false;
21140                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21141                 // permission (same as profileControl).
21142                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21143                         != PackageManager.PERMISSION_GRANTED) {
21144                     throw new SecurityException("Requires permission "
21145                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21146                 }
21147
21148                 if (fd == null) {
21149                     throw new IllegalArgumentException("null fd");
21150                 }
21151
21152                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21153                 pw.println("Binder transaction traces for all processes.\n");
21154                 for (ProcessRecord process : mLruProcesses) {
21155                     if (!processSanityChecksLocked(process)) {
21156                         continue;
21157                     }
21158
21159                     pw.println("Traces for process: " + process.processName);
21160                     pw.flush();
21161                     try {
21162                         TransferPipe tp = new TransferPipe();
21163                         try {
21164                             process.thread.stopBinderTrackingAndDump(
21165                                     tp.getWriteFd().getFileDescriptor());
21166                             tp.go(fd.getFileDescriptor());
21167                         } finally {
21168                             tp.kill();
21169                         }
21170                     } catch (IOException e) {
21171                         pw.println("Failure while dumping IPC traces from " + process +
21172                                 ".  Exception: " + e);
21173                         pw.flush();
21174                     } catch (RemoteException e) {
21175                         pw.println("Got a RemoteException while dumping IPC traces from " +
21176                                 process + ".  Exception: " + e);
21177                         pw.flush();
21178                     }
21179                 }
21180                 fd = null;
21181                 return true;
21182             }
21183         } finally {
21184             if (fd != null) {
21185                 try {
21186                     fd.close();
21187                 } catch (IOException e) {
21188                 }
21189             }
21190         }
21191     }
21192
21193     private final class LocalService extends ActivityManagerInternal {
21194         @Override
21195         public void onWakefulnessChanged(int wakefulness) {
21196             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21197         }
21198
21199         @Override
21200         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21201                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21202             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21203                     processName, abiOverride, uid, crashHandler);
21204         }
21205
21206         @Override
21207         public SleepToken acquireSleepToken(String tag) {
21208             Preconditions.checkNotNull(tag);
21209
21210             synchronized (ActivityManagerService.this) {
21211                 SleepTokenImpl token = new SleepTokenImpl(tag);
21212                 mSleepTokens.add(token);
21213                 updateSleepIfNeededLocked();
21214                 applyVrModeIfNeededLocked(mFocusedActivity, false);
21215                 return token;
21216             }
21217         }
21218
21219         @Override
21220         public ComponentName getHomeActivityForUser(int userId) {
21221             synchronized (ActivityManagerService.this) {
21222                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21223                 return homeActivity == null ? null : homeActivity.realActivity;
21224             }
21225         }
21226
21227         @Override
21228         public void onUserRemoved(int userId) {
21229             synchronized (ActivityManagerService.this) {
21230                 ActivityManagerService.this.onUserStoppedLocked(userId);
21231             }
21232         }
21233
21234         @Override
21235         public void onLocalVoiceInteractionStarted(IBinder activity,
21236                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21237             synchronized (ActivityManagerService.this) {
21238                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21239                         voiceSession, voiceInteractor);
21240             }
21241         }
21242
21243         @Override
21244         public void notifyStartingWindowDrawn() {
21245             synchronized (ActivityManagerService.this) {
21246                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21247             }
21248         }
21249
21250         @Override
21251         public void notifyAppTransitionStarting(int reason) {
21252             synchronized (ActivityManagerService.this) {
21253                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21254             }
21255         }
21256
21257         @Override
21258         public void notifyAppTransitionFinished() {
21259             synchronized (ActivityManagerService.this) {
21260                 mStackSupervisor.notifyAppTransitionDone();
21261             }
21262         }
21263
21264         @Override
21265         public void notifyAppTransitionCancelled() {
21266             synchronized (ActivityManagerService.this) {
21267                 mStackSupervisor.notifyAppTransitionDone();
21268             }
21269         }
21270
21271         @Override
21272         public List<IBinder> getTopVisibleActivities() {
21273             synchronized (ActivityManagerService.this) {
21274                 return mStackSupervisor.getTopVisibleActivities();
21275             }
21276         }
21277
21278         @Override
21279         public void notifyDockedStackMinimizedChanged(boolean minimized) {
21280             synchronized (ActivityManagerService.this) {
21281                 mStackSupervisor.setDockedStackMinimized(minimized);
21282             }
21283         }
21284
21285         @Override
21286         public void killForegroundAppsForUser(int userHandle) {
21287             synchronized (ActivityManagerService.this) {
21288                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21289                 final int NP = mProcessNames.getMap().size();
21290                 for (int ip = 0; ip < NP; ip++) {
21291                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21292                     final int NA = apps.size();
21293                     for (int ia = 0; ia < NA; ia++) {
21294                         final ProcessRecord app = apps.valueAt(ia);
21295                         if (app.persistent) {
21296                             // We don't kill persistent processes.
21297                             continue;
21298                         }
21299                         if (app.removed) {
21300                             procs.add(app);
21301                         } else if (app.userId == userHandle && app.foregroundActivities) {
21302                             app.removed = true;
21303                             procs.add(app);
21304                         }
21305                     }
21306                 }
21307
21308                 final int N = procs.size();
21309                 for (int i = 0; i < N; i++) {
21310                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
21311                 }
21312             }
21313         }
21314     }
21315
21316     private final class SleepTokenImpl extends SleepToken {
21317         private final String mTag;
21318         private final long mAcquireTime;
21319
21320         public SleepTokenImpl(String tag) {
21321             mTag = tag;
21322             mAcquireTime = SystemClock.uptimeMillis();
21323         }
21324
21325         @Override
21326         public void release() {
21327             synchronized (ActivityManagerService.this) {
21328                 if (mSleepTokens.remove(this)) {
21329                     updateSleepIfNeededLocked();
21330                 }
21331             }
21332         }
21333
21334         @Override
21335         public String toString() {
21336             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21337         }
21338     }
21339
21340     /**
21341      * An implementation of IAppTask, that allows an app to manage its own tasks via
21342      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21343      * only the process that calls getAppTasks() can call the AppTask methods.
21344      */
21345     class AppTaskImpl extends IAppTask.Stub {
21346         private int mTaskId;
21347         private int mCallingUid;
21348
21349         public AppTaskImpl(int taskId, int callingUid) {
21350             mTaskId = taskId;
21351             mCallingUid = callingUid;
21352         }
21353
21354         private void checkCaller() {
21355             if (mCallingUid != Binder.getCallingUid()) {
21356                 throw new SecurityException("Caller " + mCallingUid
21357                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21358             }
21359         }
21360
21361         @Override
21362         public void finishAndRemoveTask() {
21363             checkCaller();
21364
21365             synchronized (ActivityManagerService.this) {
21366                 long origId = Binder.clearCallingIdentity();
21367                 try {
21368                     // We remove the task from recents to preserve backwards
21369                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21370                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21371                     }
21372                 } finally {
21373                     Binder.restoreCallingIdentity(origId);
21374                 }
21375             }
21376         }
21377
21378         @Override
21379         public ActivityManager.RecentTaskInfo getTaskInfo() {
21380             checkCaller();
21381
21382             synchronized (ActivityManagerService.this) {
21383                 long origId = Binder.clearCallingIdentity();
21384                 try {
21385                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21386                     if (tr == null) {
21387                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21388                     }
21389                     return createRecentTaskInfoFromTaskRecord(tr);
21390                 } finally {
21391                     Binder.restoreCallingIdentity(origId);
21392                 }
21393             }
21394         }
21395
21396         @Override
21397         public void moveToFront() {
21398             checkCaller();
21399             // Will bring task to front if it already has a root activity.
21400             final long origId = Binder.clearCallingIdentity();
21401             try {
21402                 synchronized (this) {
21403                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21404                 }
21405             } finally {
21406                 Binder.restoreCallingIdentity(origId);
21407             }
21408         }
21409
21410         @Override
21411         public int startActivity(IBinder whoThread, String callingPackage,
21412                 Intent intent, String resolvedType, Bundle bOptions) {
21413             checkCaller();
21414
21415             int callingUser = UserHandle.getCallingUserId();
21416             TaskRecord tr;
21417             IApplicationThread appThread;
21418             synchronized (ActivityManagerService.this) {
21419                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21420                 if (tr == null) {
21421                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21422                 }
21423                 appThread = ApplicationThreadNative.asInterface(whoThread);
21424                 if (appThread == null) {
21425                     throw new IllegalArgumentException("Bad app thread " + appThread);
21426                 }
21427             }
21428             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21429                     resolvedType, null, null, null, null, 0, 0, null, null,
21430                     null, bOptions, false, callingUser, null, tr);
21431         }
21432
21433         @Override
21434         public void setExcludeFromRecents(boolean exclude) {
21435             checkCaller();
21436
21437             synchronized (ActivityManagerService.this) {
21438                 long origId = Binder.clearCallingIdentity();
21439                 try {
21440                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21441                     if (tr == null) {
21442                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21443                     }
21444                     Intent intent = tr.getBaseIntent();
21445                     if (exclude) {
21446                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21447                     } else {
21448                         intent.setFlags(intent.getFlags()
21449                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21450                     }
21451                 } finally {
21452                     Binder.restoreCallingIdentity(origId);
21453                 }
21454             }
21455         }
21456     }
21457
21458     /**
21459      * Kill processes for the user with id userId and that depend on the package named packageName
21460      */
21461     @Override
21462     public void killPackageDependents(String packageName, int userId) {
21463         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21464         if (packageName == null) {
21465             throw new NullPointerException(
21466                     "Cannot kill the dependents of a package without its name.");
21467         }
21468
21469         long callingId = Binder.clearCallingIdentity();
21470         IPackageManager pm = AppGlobals.getPackageManager();
21471         int pkgUid = -1;
21472         try {
21473             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21474         } catch (RemoteException e) {
21475         }
21476         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21477             throw new IllegalArgumentException(
21478                     "Cannot kill dependents of non-existing package " + packageName);
21479         }
21480         try {
21481             synchronized(this) {
21482                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21483                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21484                         "dep: " + packageName);
21485             }
21486         } finally {
21487             Binder.restoreCallingIdentity(callingId);
21488         }
21489     }
21490 }