OSDN Git Service

Prevent crash from null ApplicationInfo after package is removed.
[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_LEANBACK_ONLY;
271 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
272 import static android.content.pm.PackageManager.GET_PROVIDERS;
273 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
274 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
275 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
276 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
277 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
278 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
279 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
280 import static android.provider.Settings.Global.DEBUG_APP;
281 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
282 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
283 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
284 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
285 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
286 import static android.provider.Settings.System.FONT_SCALE;
287 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
288 import static com.android.internal.util.XmlUtils.readIntAttribute;
289 import static com.android.internal.util.XmlUtils.readLongAttribute;
290 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.writeIntAttribute;
292 import static com.android.internal.util.XmlUtils.writeLongAttribute;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
350 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
351 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
352 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
353 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
354 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
355 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
356 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
357 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
358 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
359 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
360 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
361 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
363 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
364 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
365 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
366 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
368 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
369 import static org.xmlpull.v1.XmlPullParser.START_TAG;
370
371 public final class ActivityManagerService extends ActivityManagerNative
372         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
373
374     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
375     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
376     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
377     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
378     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
379     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
380     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
381     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
382     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
383     private static final String TAG_LRU = TAG + POSTFIX_LRU;
384     private static final String TAG_MU = TAG + POSTFIX_MU;
385     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
386     private static final String TAG_POWER = TAG + POSTFIX_POWER;
387     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
388     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
389     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
390     private static final String TAG_PSS = TAG + POSTFIX_PSS;
391     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
392     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
393     private static final String TAG_STACK = TAG + POSTFIX_STACK;
394     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
395     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
396     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
397     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
398     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
399
400     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
401     // here so that while the job scheduler can depend on AMS, the other way around
402     // need not be the case.
403     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
404
405     /** Control over CPU and battery monitoring */
406     // write battery stats every 30 minutes.
407     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
408     static final boolean MONITOR_CPU_USAGE = true;
409     // don't sample cpu less than every 5 seconds.
410     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
411     // wait possibly forever for next cpu sample.
412     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
413     static final boolean MONITOR_THREAD_CPU_USAGE = false;
414
415     // The flags that are set for all calls we make to the package manager.
416     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
417
418     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
419
420     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
421
422     // Amount of time after a call to stopAppSwitches() during which we will
423     // prevent further untrusted switches from happening.
424     static final long APP_SWITCH_DELAY_TIME = 5*1000;
425
426     // How long we wait for a launched process to attach to the activity manager
427     // before we decide it's never going to come up for real.
428     static final int PROC_START_TIMEOUT = 10*1000;
429     // How long we wait for an attached process to publish its content providers
430     // before we decide it must be hung.
431     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
432
433     // How long we will retain processes hosting content providers in the "last activity"
434     // state before allowing them to drop down to the regular cached LRU list.  This is
435     // to avoid thrashing of provider processes under low memory situations.
436     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
437
438     // How long we wait for a launched process to attach to the activity manager
439     // before we decide it's never going to come up for real, when the process was
440     // started with a wrapper for instrumentation (such as Valgrind) because it
441     // could take much longer than usual.
442     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
443
444     // How long to wait after going idle before forcing apps to GC.
445     static final int GC_TIMEOUT = 5*1000;
446
447     // The minimum amount of time between successive GC requests for a process.
448     static final int GC_MIN_INTERVAL = 60*1000;
449
450     // The minimum amount of time between successive PSS requests for a process.
451     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
452
453     // The minimum amount of time between successive PSS requests for a process
454     // when the request is due to the memory state being lowered.
455     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
456
457     // The rate at which we check for apps using excessive power -- 15 mins.
458     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
459
460     // The minimum sample duration we will allow before deciding we have
461     // enough data on wake locks to start killing things.
462     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
463
464     // The minimum sample duration we will allow before deciding we have
465     // enough data on CPU usage to start killing things.
466     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467
468     // How long we allow a receiver to run before giving up on it.
469     static final int BROADCAST_FG_TIMEOUT = 10*1000;
470     static final int BROADCAST_BG_TIMEOUT = 60*1000;
471
472     // How long we wait until we timeout on key dispatching.
473     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
474
475     // How long we wait until we timeout on key dispatching during instrumentation.
476     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
477
478     // This is the amount of time an app needs to be running a foreground service before
479     // we will consider it to be doing interaction for usage stats.
480     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
481
482     // Maximum amount of time we will allow to elapse before re-reporting usage stats
483     // interaction with foreground processes.
484     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
485
486     // This is the amount of time we allow an app to settle after it goes into the background,
487     // before we start restricting what it can do.
488     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
489
490     // How long to wait in getAssistContextExtras for the activity and foreground services
491     // to respond with the result.
492     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
493
494     // How long top wait when going through the modern assist (which doesn't need to block
495     // on getting this result before starting to launch its UI).
496     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
497
498     // Maximum number of persisted Uri grants a package is allowed
499     static final int MAX_PERSISTED_URI_GRANTS = 128;
500
501     static final int MY_PID = Process.myPid();
502
503     static final String[] EMPTY_STRING_ARRAY = new String[0];
504
505     // How many bytes to write into the dropbox log before truncating
506     static final int DROPBOX_MAX_SIZE = 256 * 1024;
507
508     // Access modes for handleIncomingUser.
509     static final int ALLOW_NON_FULL = 0;
510     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
511     static final int ALLOW_FULL_ONLY = 2;
512
513     // Delay in notifying task stack change listeners (in millis)
514     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
515
516     // Necessary ApplicationInfo flags to mark an app as persistent
517     private static final int PERSISTENT_MASK =
518             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
519
520     // Intent sent when remote bugreport collection has been completed
521     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
522             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
523
524     // Delay to disable app launch boost
525     static final int APP_BOOST_MESSAGE_DELAY = 3000;
526     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
527     static final int APP_BOOST_TIMEOUT = 2500;
528
529     // Used to indicate that a task is removed it should also be removed from recents.
530     private static final boolean REMOVE_FROM_RECENTS = true;
531     // Used to indicate that an app transition should be animated.
532     static final boolean ANIMATE = true;
533
534     // Determines whether to take full screen screenshots
535     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
536     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
537
538     private static native int nativeMigrateToBoost();
539     private static native int nativeMigrateFromBoost();
540     private boolean mIsBoosted = false;
541     private long mBoostStartTime = 0;
542
543     /** All system services */
544     SystemServiceManager mSystemServiceManager;
545
546     private Installer mInstaller;
547
548     /** Run all ActivityStacks through this */
549     final ActivityStackSupervisor mStackSupervisor;
550
551     final ActivityStarter mActivityStarter;
552
553     /** Task stack change listeners. */
554     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
555             new RemoteCallbackList<ITaskStackListener>();
556
557     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559     public IntentFirewall mIntentFirewall;
560
561     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562     // default actuion automatically.  Important for devices without direct input
563     // devices.
564     private boolean mShowDialogs = true;
565     private boolean mInVrMode = false;
566
567     BroadcastQueue mFgBroadcastQueue;
568     BroadcastQueue mBgBroadcastQueue;
569     // Convenient for easy iteration over the queues. Foreground is first
570     // so that dispatch of foreground broadcasts gets precedence.
571     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
572
573     BroadcastQueue broadcastQueueForIntent(Intent intent) {
574         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                 "Broadcast intent " + intent + " on "
577                 + (isFg ? "foreground" : "background") + " queue");
578         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579     }
580
581     /**
582      * Activity we have told the window manager to have key focus.
583      */
584     ActivityRecord mFocusedActivity = null;
585
586     /**
587      * User id of the last activity mFocusedActivity was set to.
588      */
589     private int mLastFocusedUserId;
590
591     /**
592      * If non-null, we are tracking the time the user spends in the currently focused app.
593      */
594     private AppTimeTracker mCurAppTimeTracker;
595
596     /**
597      * List of intents that were used to start the most recent tasks.
598      */
599     final RecentTasks mRecentTasks;
600
601     /**
602      * For addAppTask: cached of the last activity component that was added.
603      */
604     ComponentName mLastAddedTaskComponent;
605
606     /**
607      * For addAppTask: cached of the last activity uid that was added.
608      */
609     int mLastAddedTaskUid;
610
611     /**
612      * For addAppTask: cached of the last ActivityInfo that was added.
613      */
614     ActivityInfo mLastAddedTaskActivity;
615
616     /**
617      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618      */
619     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621     /**
622      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623      */
624     String mDeviceOwnerName;
625
626     final UserController mUserController;
627
628     final AppErrors mAppErrors;
629
630     boolean mDoingSetFocusedActivity;
631
632     public boolean canShowErrorDialogs() {
633         return mShowDialogs && !mSleeping && !mShuttingDown;
634     }
635
636     // it's a semaphore; boost when 0->1, reset when 1->0
637     static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638         @Override protected Integer initialValue() {
639             return 0;
640         }
641     };
642
643     static void boostPriorityForLockedSection() {
644         if (sIsBoosted.get() == 0) {
645             // boost to prio 118 while holding a global lock
646             Process.setThreadPriority(Process.myTid(), -2);
647             //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648         }
649         int cur = sIsBoosted.get();
650         sIsBoosted.set(cur + 1);
651     }
652
653     static void resetPriorityAfterLockedSection() {
654         sIsBoosted.set(sIsBoosted.get() - 1);
655         if (sIsBoosted.get() == 0) {
656             //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657             Process.setThreadPriority(Process.myTid(), 0);
658         }
659     }
660     public class PendingAssistExtras extends Binder implements Runnable {
661         public final ActivityRecord activity;
662         public final Bundle extras;
663         public final Intent intent;
664         public final String hint;
665         public final IResultReceiver receiver;
666         public final int userHandle;
667         public boolean haveResult = false;
668         public Bundle result = null;
669         public AssistStructure structure = null;
670         public AssistContent content = null;
671         public Bundle receiverExtras;
672
673         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675             activity = _activity;
676             extras = _extras;
677             intent = _intent;
678             hint = _hint;
679             receiver = _receiver;
680             receiverExtras = _receiverExtras;
681             userHandle = _userHandle;
682         }
683         @Override
684         public void run() {
685             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686             synchronized (this) {
687                 haveResult = true;
688                 notifyAll();
689             }
690             pendingAssistExtrasTimedOut(this);
691         }
692     }
693
694     final ArrayList<PendingAssistExtras> mPendingAssistExtras
695             = new ArrayList<PendingAssistExtras>();
696
697     /**
698      * Process management.
699      */
700     final ProcessList mProcessList = new ProcessList();
701
702     /**
703      * All of the applications we currently have running organized by name.
704      * The keys are strings of the application package name (as
705      * returned by the package manager), and the keys are ApplicationRecord
706      * objects.
707      */
708     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710     /**
711      * Tracking long-term execution of processes to look for abuse and other
712      * bad app behavior.
713      */
714     final ProcessStatsService mProcessStats;
715
716     /**
717      * The currently running isolated processes.
718      */
719     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721     /**
722      * Counter for assigning isolated process uids, to avoid frequently reusing the
723      * same ones.
724      */
725     int mNextIsolatedProcessUid = 0;
726
727     /**
728      * The currently running heavy-weight process, if any.
729      */
730     ProcessRecord mHeavyWeightProcess = null;
731
732     /**
733      * All of the processes we currently have running organized by pid.
734      * The keys are the pid running the application.
735      *
736      * <p>NOTE: This object is protected by its own lock, NOT the global
737      * activity manager lock!
738      */
739     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741     /**
742      * All of the processes that have been forced to be foreground.  The key
743      * is the pid of the caller who requested it (we hold a death
744      * link on it).
745      */
746     abstract class ForegroundToken implements IBinder.DeathRecipient {
747         int pid;
748         IBinder token;
749     }
750     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752     /**
753      * List of records for processes that someone had tried to start before the
754      * system was ready.  We don't start them at that point, but ensure they
755      * are started by the time booting is complete.
756      */
757     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759     /**
760      * List of persistent applications that are in the process
761      * of being started.
762      */
763     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765     /**
766      * Processes that are being forcibly torn down.
767      */
768     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770     /**
771      * List of running applications, sorted by recent usage.
772      * The first entry in the list is the least recently used.
773      */
774     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776     /**
777      * Where in mLruProcesses that the processes hosting activities start.
778      */
779     int mLruProcessActivityStart = 0;
780
781     /**
782      * Where in mLruProcesses that the processes hosting services start.
783      * This is after (lower index) than mLruProcessesActivityStart.
784      */
785     int mLruProcessServiceStart = 0;
786
787     /**
788      * List of processes that should gc as soon as things are idle.
789      */
790     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792     /**
793      * Processes we want to collect PSS data from.
794      */
795     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797     private boolean mBinderTransactionTrackingEnabled = false;
798
799     /**
800      * Last time we requested PSS data of all processes.
801      */
802     long mLastFullPssTime = SystemClock.uptimeMillis();
803
804     /**
805      * If set, the next time we collect PSS data we should do a full collection
806      * with data from native processes and the kernel.
807      */
808     boolean mFullPssPending = false;
809
810     /**
811      * This is the process holding what we currently consider to be
812      * the "home" activity.
813      */
814     ProcessRecord mHomeProcess;
815
816     /**
817      * This is the process holding the activity the user last visited that
818      * is in a different process from the one they are currently in.
819      */
820     ProcessRecord mPreviousProcess;
821
822     /**
823      * The time at which the previous process was last visible.
824      */
825     long mPreviousProcessVisibleTime;
826
827     /**
828      * Track all uids that have actively running processes.
829      */
830     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832     /**
833      * This is for verifying the UID report flow.
834      */
835     static final boolean VALIDATE_UID_STATES = true;
836     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838     /**
839      * Packages that the user has asked to have run in screen size
840      * compatibility mode instead of filling the screen.
841      */
842     final CompatModePackages mCompatModePackages;
843
844     /**
845      * Set of IntentSenderRecord objects that are currently active.
846      */
847     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850     /**
851      * Fingerprints (hashCode()) of stack traces that we've
852      * already logged DropBox entries for.  Guarded by itself.  If
853      * something (rogue user app) forces this over
854      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855      */
856     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859     /**
860      * Strict Mode background batched logging state.
861      *
862      * The string buffer is guarded by itself, and its lock is also
863      * used to determine if another batched write is already
864      * in-flight.
865      */
866     private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868     /**
869      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871      */
872     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874     /**
875      * Resolver for broadcast intents to registered receivers.
876      * Holds BroadcastFilter (subclass of IntentFilter).
877      */
878     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880         @Override
881         protected boolean allowFilterResult(
882                 BroadcastFilter filter, List<BroadcastFilter> dest) {
883             IBinder target = filter.receiverList.receiver.asBinder();
884             for (int i = dest.size() - 1; i >= 0; i--) {
885                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                     return false;
887                 }
888             }
889             return true;
890         }
891
892         @Override
893         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                     || userId == filter.owningUserId) {
896                 return super.newResult(filter, match, userId);
897             }
898             return null;
899         }
900
901         @Override
902         protected BroadcastFilter[] newArray(int size) {
903             return new BroadcastFilter[size];
904         }
905
906         @Override
907         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908             return packageName.equals(filter.packageName);
909         }
910     };
911
912     /**
913      * State of all active sticky broadcasts per user.  Keys are the action of the
914      * sticky Intent, values are an ArrayList of all broadcasted intents with
915      * that action (which should usually be one).  The SparseArray is keyed
916      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917      * for stickies that are sent to all users.
918      */
919     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922     final ActiveServices mServices;
923
924     final static class Association {
925         final int mSourceUid;
926         final String mSourceProcess;
927         final int mTargetUid;
928         final ComponentName mTargetComponent;
929         final String mTargetProcess;
930
931         int mCount;
932         long mTime;
933
934         int mNesting;
935         long mStartTime;
936
937         // states of the source process when the bind occurred.
938         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939         long mLastStateUptime;
940         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                 - ActivityManager.MIN_PROCESS_STATE+1];
942
943         Association(int sourceUid, String sourceProcess, int targetUid,
944                 ComponentName targetComponent, String targetProcess) {
945             mSourceUid = sourceUid;
946             mSourceProcess = sourceProcess;
947             mTargetUid = targetUid;
948             mTargetComponent = targetComponent;
949             mTargetProcess = targetProcess;
950         }
951     }
952
953     /**
954      * When service association tracking is enabled, this is all of the associations we
955      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956      * -> association data.
957      */
958     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959             mAssociations = new SparseArray<>();
960     boolean mTrackingAssociations;
961
962     /**
963      * Backup/restore process management
964      */
965     String mBackupAppName = null;
966     BackupRecord mBackupTarget = null;
967
968     final ProviderMap mProviderMap;
969
970     /**
971      * List of content providers who have clients waiting for them.  The
972      * application is currently being launched and the provider will be
973      * removed from this list once it is published.
974      */
975     final ArrayList<ContentProviderRecord> mLaunchingProviders
976             = new ArrayList<ContentProviderRecord>();
977
978     /**
979      * File storing persisted {@link #mGrantedUriPermissions}.
980      */
981     private final AtomicFile mGrantFile;
982
983     /** XML constants used in {@link #mGrantFile} */
984     private static final String TAG_URI_GRANTS = "uri-grants";
985     private static final String TAG_URI_GRANT = "uri-grant";
986     private static final String ATTR_USER_HANDLE = "userHandle";
987     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988     private static final String ATTR_TARGET_USER_ID = "targetUserId";
989     private static final String ATTR_SOURCE_PKG = "sourcePkg";
990     private static final String ATTR_TARGET_PKG = "targetPkg";
991     private static final String ATTR_URI = "uri";
992     private static final String ATTR_MODE_FLAGS = "modeFlags";
993     private static final String ATTR_CREATED_TIME = "createdTime";
994     private static final String ATTR_PREFIX = "prefix";
995
996     /**
997      * Global set of specific {@link Uri} permissions that have been granted.
998      * This optimized lookup structure maps from {@link UriPermission#targetUid}
999      * to {@link UriPermission#uri} to {@link UriPermission}.
1000      */
1001     @GuardedBy("this")
1002     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005     public static class GrantUri {
1006         public final int sourceUserId;
1007         public final Uri uri;
1008         public boolean prefix;
1009
1010         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011             this.sourceUserId = sourceUserId;
1012             this.uri = uri;
1013             this.prefix = prefix;
1014         }
1015
1016         @Override
1017         public int hashCode() {
1018             int hashCode = 1;
1019             hashCode = 31 * hashCode + sourceUserId;
1020             hashCode = 31 * hashCode + uri.hashCode();
1021             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022             return hashCode;
1023         }
1024
1025         @Override
1026         public boolean equals(Object o) {
1027             if (o instanceof GrantUri) {
1028                 GrantUri other = (GrantUri) o;
1029                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                         && prefix == other.prefix;
1031             }
1032             return false;
1033         }
1034
1035         @Override
1036         public String toString() {
1037             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038             if (prefix) result += " [prefix]";
1039             return result;
1040         }
1041
1042         public String toSafeString() {
1043             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044             if (prefix) result += " [prefix]";
1045             return result;
1046         }
1047
1048         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                     ContentProvider.getUriWithoutUserId(uri), false);
1051         }
1052     }
1053
1054     CoreSettingsObserver mCoreSettingsObserver;
1055
1056     FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058     private final class FontScaleSettingObserver extends ContentObserver {
1059         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061         public FontScaleSettingObserver() {
1062             super(mHandler);
1063             ContentResolver resolver = mContext.getContentResolver();
1064             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065         }
1066
1067         @Override
1068         public void onChange(boolean selfChange, Uri uri) {
1069             if (mFontScaleUri.equals(uri)) {
1070                 updateFontScaleIfNeeded();
1071             }
1072         }
1073     }
1074
1075     /**
1076      * Thread-local storage used to carry caller permissions over through
1077      * indirect content-provider access.
1078      */
1079     private class Identity {
1080         public final IBinder token;
1081         public final int pid;
1082         public final int uid;
1083
1084         Identity(IBinder _token, int _pid, int _uid) {
1085             token = _token;
1086             pid = _pid;
1087             uid = _uid;
1088         }
1089     }
1090
1091     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093     /**
1094      * All information we have collected about the runtime performance of
1095      * any user id that can impact battery performance.
1096      */
1097     final BatteryStatsService mBatteryStatsService;
1098
1099     /**
1100      * Information about component usage
1101      */
1102     UsageStatsManagerInternal mUsageStatsService;
1103
1104     /**
1105      * Access to DeviceIdleController service.
1106      */
1107     DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109     /**
1110      * Information about and control over application operations
1111      */
1112     final AppOpsService mAppOpsService;
1113
1114     /**
1115      * Current configuration information.  HistoryRecord objects are given
1116      * a reference to this object to indicate which configuration they are
1117      * currently running in, so this object must be kept immutable.
1118      */
1119     Configuration mConfiguration = new Configuration();
1120
1121     /**
1122      * Current sequencing integer of the configuration, for skipping old
1123      * configurations.
1124      */
1125     int mConfigurationSeq = 0;
1126
1127     boolean mSuppressResizeConfigChanges = false;
1128
1129     /**
1130      * Hardware-reported OpenGLES version.
1131      */
1132     final int GL_ES_VERSION;
1133
1134     /**
1135      * List of initialization arguments to pass to all processes when binding applications to them.
1136      * For example, references to the commonly used services.
1137      */
1138     HashMap<String, IBinder> mAppBindArgs;
1139
1140     /**
1141      * Temporary to avoid allocations.  Protected by main lock.
1142      */
1143     final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145     /**
1146      * Used to control how we initialize the service.
1147      */
1148     ComponentName mTopComponent;
1149     String mTopAction = Intent.ACTION_MAIN;
1150     String mTopData;
1151
1152     volatile boolean mProcessesReady = false;
1153     volatile boolean mSystemReady = false;
1154     volatile boolean mOnBattery = false;
1155     volatile int mFactoryTest;
1156
1157     @GuardedBy("this") boolean mBooting = false;
1158     @GuardedBy("this") boolean mCallFinishBooting = false;
1159     @GuardedBy("this") boolean mBootAnimationComplete = false;
1160     @GuardedBy("this") boolean mLaunchWarningShown = false;
1161     @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163     Context mContext;
1164
1165     /**
1166      * The time at which we will allow normal application switches again,
1167      * after a call to {@link #stopAppSwitches()}.
1168      */
1169     long mAppSwitchesAllowedTime;
1170
1171     /**
1172      * This is set to true after the first switch after mAppSwitchesAllowedTime
1173      * is set; any switches after that will clear the time.
1174      */
1175     boolean mDidAppSwitch;
1176
1177     /**
1178      * Last time (in realtime) at which we checked for power usage.
1179      */
1180     long mLastPowerCheckRealtime;
1181
1182     /**
1183      * Last time (in uptime) at which we checked for power usage.
1184      */
1185     long mLastPowerCheckUptime;
1186
1187     /**
1188      * Set while we are wanting to sleep, to prevent any
1189      * activities from being started/resumed.
1190      */
1191     private boolean mSleeping = false;
1192
1193     /**
1194      * The process state used for processes that are running the top activities.
1195      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196      */
1197     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199     /**
1200      * Set while we are running a voice interaction.  This overrides
1201      * sleeping while it is active.
1202      */
1203     private IVoiceInteractionSession mRunningVoice;
1204
1205     /**
1206      * For some direct access we need to power manager.
1207      */
1208     PowerManagerInternal mLocalPowerManager;
1209
1210     /**
1211      * We want to hold a wake lock while running a voice interaction session, since
1212      * this may happen with the screen off and we need to keep the CPU running to
1213      * be able to continue to interact with the user.
1214      */
1215     PowerManager.WakeLock mVoiceWakeLock;
1216
1217     /**
1218      * State of external calls telling us if the device is awake or asleep.
1219      */
1220     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222     /**
1223      * A list of tokens that cause the top activity to be put to sleep.
1224      * They are used by components that may hide and block interaction with underlying
1225      * activities.
1226      */
1227     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229     static final int LOCK_SCREEN_HIDDEN = 0;
1230     static final int LOCK_SCREEN_LEAVING = 1;
1231     static final int LOCK_SCREEN_SHOWN = 2;
1232     /**
1233      * State of external call telling us if the lock screen is shown.
1234      */
1235     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237     /**
1238      * Set if we are shutting down the system, similar to sleeping.
1239      */
1240     boolean mShuttingDown = false;
1241
1242     /**
1243      * Current sequence id for oom_adj computation traversal.
1244      */
1245     int mAdjSeq = 0;
1246
1247     /**
1248      * Current sequence id for process LRU updating.
1249      */
1250     int mLruSeq = 0;
1251
1252     /**
1253      * Keep track of the non-cached/empty process we last found, to help
1254      * determine how to distribute cached/empty processes next time.
1255      */
1256     int mNumNonCachedProcs = 0;
1257
1258     /**
1259      * Keep track of the number of cached hidden procs, to balance oom adj
1260      * distribution between those and empty procs.
1261      */
1262     int mNumCachedHiddenProcs = 0;
1263
1264     /**
1265      * Keep track of the number of service processes we last found, to
1266      * determine on the next iteration which should be B services.
1267      */
1268     int mNumServiceProcs = 0;
1269     int mNewNumAServiceProcs = 0;
1270     int mNewNumServiceProcs = 0;
1271
1272     /**
1273      * Allow the current computed overall memory level of the system to go down?
1274      * This is set to false when we are killing processes for reasons other than
1275      * memory management, so that the now smaller process list will not be taken as
1276      * an indication that memory is tighter.
1277      */
1278     boolean mAllowLowerMemLevel = false;
1279
1280     /**
1281      * The last computed memory level, for holding when we are in a state that
1282      * processes are going away for other reasons.
1283      */
1284     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286     /**
1287      * The last total number of process we have, to determine if changes actually look
1288      * like a shrinking number of process due to lower RAM.
1289      */
1290     int mLastNumProcesses;
1291
1292     /**
1293      * The uptime of the last time we performed idle maintenance.
1294      */
1295     long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297     /**
1298      * Total time spent with RAM that has been added in the past since the last idle time.
1299      */
1300     long mLowRamTimeSinceLastIdle = 0;
1301
1302     /**
1303      * If RAM is currently low, when that horrible situation started.
1304      */
1305     long mLowRamStartTime = 0;
1306
1307     /**
1308      * For reporting to battery stats the current top application.
1309      */
1310     private String mCurResumedPackage = null;
1311     private int mCurResumedUid = -1;
1312
1313     /**
1314      * For reporting to battery stats the apps currently running foreground
1315      * service.  The ProcessMap is package/uid tuples; each of these contain
1316      * an array of the currently foreground processes.
1317      */
1318     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319             = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321     /**
1322      * This is set if we had to do a delayed dexopt of an app before launching
1323      * it, to increase the ANR timeouts in that case.
1324      */
1325     boolean mDidDexOpt;
1326
1327     /**
1328      * Set if the systemServer made a call to enterSafeMode.
1329      */
1330     boolean mSafeMode;
1331
1332     /**
1333      * If true, we are running under a test environment so will sample PSS from processes
1334      * much more rapidly to try to collect better data when the tests are rapidly
1335      * running through apps.
1336      */
1337     boolean mTestPssMode = false;
1338
1339     String mDebugApp = null;
1340     boolean mWaitForDebugger = false;
1341     boolean mDebugTransient = false;
1342     String mOrigDebugApp = null;
1343     boolean mOrigWaitForDebugger = false;
1344     boolean mAlwaysFinishActivities = false;
1345     boolean mLenientBackgroundCheck = false;
1346     boolean mForceResizableActivities;
1347     boolean mSupportsMultiWindow;
1348     boolean mSupportsFreeformWindowManagement;
1349     boolean mSupportsPictureInPicture;
1350     boolean mSupportsLeanbackOnly;
1351     Rect mDefaultPinnedStackBounds;
1352     IActivityController mController = null;
1353     boolean mControllerIsAMonkey = false;
1354     String mProfileApp = null;
1355     ProcessRecord mProfileProc = null;
1356     String mProfileFile;
1357     ParcelFileDescriptor mProfileFd;
1358     int mSamplingInterval = 0;
1359     boolean mAutoStopProfiler = false;
1360     int mProfileType = 0;
1361     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362     String mMemWatchDumpProcName;
1363     String mMemWatchDumpFile;
1364     int mMemWatchDumpPid;
1365     int mMemWatchDumpUid;
1366     String mTrackAllocationApp = null;
1367     String mNativeDebuggingApp = null;
1368
1369     final long[] mTmpLong = new long[2];
1370
1371     static final class ProcessChangeItem {
1372         static final int CHANGE_ACTIVITIES = 1<<0;
1373         static final int CHANGE_PROCESS_STATE = 1<<1;
1374         int changes;
1375         int uid;
1376         int pid;
1377         int processState;
1378         boolean foregroundActivities;
1379     }
1380
1381     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393     /**
1394      * Runtime CPU use collection thread.  This object's lock is used to
1395      * perform synchronization with the thread (notifying it to run).
1396      */
1397     final Thread mProcessCpuThread;
1398
1399     /**
1400      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401      * Must acquire this object's lock when accessing it.
1402      * NOTE: this lock will be held while doing long operations (trawling
1403      * through all processes in /proc), so it should never be acquired by
1404      * any critical paths such as when holding the main activity manager lock.
1405      */
1406     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407             MONITOR_THREAD_CPU_USAGE);
1408     final AtomicLong mLastCpuTime = new AtomicLong(0);
1409     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411     long mLastWriteTime = 0;
1412
1413     /**
1414      * Used to retain an update lock when the foreground activity is in
1415      * immersive mode.
1416      */
1417     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419     /**
1420      * Set to true after the system has finished booting.
1421      */
1422     boolean mBooted = false;
1423
1424     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425     int mProcessLimitOverride = -1;
1426
1427     WindowManagerService mWindowManager;
1428     final ActivityThread mSystemThread;
1429
1430     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431         final ProcessRecord mApp;
1432         final int mPid;
1433         final IApplicationThread mAppThread;
1434
1435         AppDeathRecipient(ProcessRecord app, int pid,
1436                 IApplicationThread thread) {
1437             if (DEBUG_ALL) Slog.v(
1438                 TAG, "New death recipient " + this
1439                 + " for thread " + thread.asBinder());
1440             mApp = app;
1441             mPid = pid;
1442             mAppThread = thread;
1443         }
1444
1445         @Override
1446         public void binderDied() {
1447             if (DEBUG_ALL) Slog.v(
1448                 TAG, "Death received in " + this
1449                 + " for thread " + mAppThread.asBinder());
1450             synchronized(ActivityManagerService.this) {
1451                 appDiedLocked(mApp, mPid, mAppThread, true);
1452             }
1453         }
1454     }
1455
1456     static final int SHOW_ERROR_UI_MSG = 1;
1457     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459     static final int UPDATE_CONFIGURATION_MSG = 4;
1460     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462     static final int SERVICE_TIMEOUT_MSG = 12;
1463     static final int UPDATE_TIME_ZONE = 13;
1464     static final int SHOW_UID_ERROR_UI_MSG = 14;
1465     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466     static final int PROC_START_TIMEOUT_MSG = 20;
1467     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468     static final int KILL_APPLICATION_MSG = 22;
1469     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474     static final int CLEAR_DNS_CACHE_MSG = 28;
1475     static final int UPDATE_HTTP_PROXY_MSG = 29;
1476     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479     static final int REPORT_MEM_USAGE_MSG = 33;
1480     static final int REPORT_USER_SWITCH_MSG = 34;
1481     static final int CONTINUE_USER_SWITCH_MSG = 35;
1482     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484     static final int PERSIST_URI_GRANTS_MSG = 38;
1485     static final int REQUEST_ALL_PSS_MSG = 39;
1486     static final int START_PROFILES_MSG = 40;
1487     static final int UPDATE_TIME = 41;
1488     static final int SYSTEM_USER_START_MSG = 42;
1489     static final int SYSTEM_USER_CURRENT_MSG = 43;
1490     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491     static final int FINISH_BOOTING_MSG = 45;
1492     static final int START_USER_SWITCH_UI_MSG = 46;
1493     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494     static final int DISMISS_DIALOG_UI_MSG = 48;
1495     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498     static final int DELETE_DUMPHEAP_MSG = 52;
1499     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501     static final int REPORT_TIME_TRACKER_MSG = 55;
1502     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506     static final int IDLE_UIDS_MSG = 60;
1507     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508     static final int LOG_STACK_STATE = 62;
1509     static final int VR_MODE_CHANGE_MSG = 63;
1510     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519     static final int FIRST_COMPAT_MODE_MSG = 300;
1520     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522     static ServiceThread sKillThread = null;
1523     static KillHandler sKillHandler = null;
1524
1525     CompatModeDialog mCompatModeDialog;
1526     long mLastMemUsageReportTime = 0;
1527
1528     /**
1529      * Flag whether the current user is a "monkey", i.e. whether
1530      * the UI is driven by a UI automation tool.
1531      */
1532     private boolean mUserIsMonkey;
1533
1534     /** Flag whether the device has a Recents UI */
1535     boolean mHasRecents;
1536
1537     /** The dimensions of the thumbnails in the Recents UI. */
1538     int mThumbnailWidth;
1539     int mThumbnailHeight;
1540     float mFullscreenThumbnailScale;
1541
1542     final ServiceThread mHandlerThread;
1543     final MainHandler mHandler;
1544     final UiHandler mUiHandler;
1545
1546     PackageManagerInternal mPackageManagerInt;
1547
1548     // VoiceInteraction session ID that changes for each new request except when
1549     // being called for multiwindow assist in a single session.
1550     private int mViSessionId = 1000;
1551
1552     final class KillHandler extends Handler {
1553         static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555         public KillHandler(Looper looper) {
1556             super(looper, null, true);
1557         }
1558
1559         @Override
1560         public void handleMessage(Message msg) {
1561             switch (msg.what) {
1562                 case KILL_PROCESS_GROUP_MSG:
1563                 {
1564                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                 }
1568                 break;
1569
1570                 default:
1571                     super.handleMessage(msg);
1572             }
1573         }
1574     }
1575
1576     final class UiHandler extends Handler {
1577         public UiHandler() {
1578             super(com.android.server.UiThread.get().getLooper(), null, true);
1579         }
1580
1581         @Override
1582         public void handleMessage(Message msg) {
1583             switch (msg.what) {
1584             case SHOW_ERROR_UI_MSG: {
1585                 mAppErrors.handleShowAppErrorUi(msg);
1586                 ensureBootCompleted();
1587             } break;
1588             case SHOW_NOT_RESPONDING_UI_MSG: {
1589                 mAppErrors.handleShowAnrUi(msg);
1590                 ensureBootCompleted();
1591             } break;
1592             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                 synchronized (ActivityManagerService.this) {
1595                     ProcessRecord proc = (ProcessRecord) data.get("app");
1596                     if (proc == null) {
1597                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                         break;
1599                     }
1600                     if (proc.crashDialog != null) {
1601                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                         return;
1603                     }
1604                     AppErrorResult res = (AppErrorResult) data.get("result");
1605                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                         Dialog d = new StrictModeViolationDialog(mContext,
1607                                 ActivityManagerService.this, res, proc);
1608                         d.show();
1609                         proc.crashDialog = d;
1610                     } else {
1611                         // The device is asleep, so just pretend that the user
1612                         // saw a crash dialog and hit "force quit".
1613                         res.set(0);
1614                     }
1615                 }
1616                 ensureBootCompleted();
1617             } break;
1618             case SHOW_FACTORY_ERROR_UI_MSG: {
1619                 Dialog d = new FactoryErrorDialog(
1620                     mContext, msg.getData().getCharSequence("msg"));
1621                 d.show();
1622                 ensureBootCompleted();
1623             } break;
1624             case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                 synchronized (ActivityManagerService.this) {
1626                     ProcessRecord app = (ProcessRecord)msg.obj;
1627                     if (msg.arg1 != 0) {
1628                         if (!app.waitedForDebugger) {
1629                             Dialog d = new AppWaitingForDebuggerDialog(
1630                                     ActivityManagerService.this,
1631                                     mContext, app);
1632                             app.waitDialog = d;
1633                             app.waitedForDebugger = true;
1634                             d.show();
1635                         }
1636                     } else {
1637                         if (app.waitDialog != null) {
1638                             app.waitDialog.dismiss();
1639                             app.waitDialog = null;
1640                         }
1641                     }
1642                 }
1643             } break;
1644             case SHOW_UID_ERROR_UI_MSG: {
1645                 if (mShowDialogs) {
1646                     AlertDialog d = new BaseErrorDialog(mContext);
1647                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                     d.setCancelable(false);
1649                     d.setTitle(mContext.getText(R.string.android_system_label));
1650                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                     d.show();
1654                 }
1655             } break;
1656             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                 if (mShowDialogs) {
1658                     AlertDialog d = new BaseErrorDialog(mContext);
1659                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                     d.setCancelable(false);
1661                     d.setTitle(mContext.getText(R.string.android_system_label));
1662                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                     d.show();
1666                 }
1667             } break;
1668             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                 synchronized (ActivityManagerService.this) {
1670                     ActivityRecord ar = (ActivityRecord) msg.obj;
1671                     if (mCompatModeDialog != null) {
1672                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                 ar.info.applicationInfo.packageName)) {
1674                             return;
1675                         }
1676                         mCompatModeDialog.dismiss();
1677                         mCompatModeDialog = null;
1678                     }
1679                     if (ar != null && false) {
1680                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                 ar.packageName)) {
1682                             int mode = mCompatModePackages.computeCompatModeLocked(
1683                                     ar.info.applicationInfo);
1684                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                 mCompatModeDialog = new CompatModeDialog(
1687                                         ActivityManagerService.this, mContext,
1688                                         ar.info.applicationInfo);
1689                                 mCompatModeDialog.show();
1690                             }
1691                         }
1692                     }
1693                 }
1694                 break;
1695             }
1696             case START_USER_SWITCH_UI_MSG: {
1697                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                 break;
1699             }
1700             case DISMISS_DIALOG_UI_MSG: {
1701                 final Dialog d = (Dialog) msg.obj;
1702                 d.dismiss();
1703                 break;
1704             }
1705             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                 dispatchProcessesChanged();
1707                 break;
1708             }
1709             case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                 final int pid = msg.arg1;
1711                 final int uid = msg.arg2;
1712                 dispatchProcessDied(pid, uid);
1713                 break;
1714             }
1715             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                 dispatchUidsChanged();
1717             } break;
1718             }
1719         }
1720     }
1721
1722     final class MainHandler extends Handler {
1723         public MainHandler(Looper looper) {
1724             super(looper, null, true);
1725         }
1726
1727         @Override
1728         public void handleMessage(Message msg) {
1729             switch (msg.what) {
1730             case UPDATE_CONFIGURATION_MSG: {
1731                 final ContentResolver resolver = mContext.getContentResolver();
1732                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                         msg.arg1);
1734             } break;
1735             case GC_BACKGROUND_PROCESSES_MSG: {
1736                 synchronized (ActivityManagerService.this) {
1737                     performAppGcsIfAppropriateLocked();
1738                 }
1739             } break;
1740             case SERVICE_TIMEOUT_MSG: {
1741                 if (mDidDexOpt) {
1742                     mDidDexOpt = false;
1743                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                     nmsg.obj = msg.obj;
1745                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                     return;
1747                 }
1748                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1749             } break;
1750             case UPDATE_TIME_ZONE: {
1751                 synchronized (ActivityManagerService.this) {
1752                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                         ProcessRecord r = mLruProcesses.get(i);
1754                         if (r.thread != null) {
1755                             try {
1756                                 r.thread.updateTimeZone();
1757                             } catch (RemoteException ex) {
1758                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                             }
1760                         }
1761                     }
1762                 }
1763             } break;
1764             case CLEAR_DNS_CACHE_MSG: {
1765                 synchronized (ActivityManagerService.this) {
1766                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                         ProcessRecord r = mLruProcesses.get(i);
1768                         if (r.thread != null) {
1769                             try {
1770                                 r.thread.clearDnsCache();
1771                             } catch (RemoteException ex) {
1772                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                             }
1774                         }
1775                     }
1776                 }
1777             } break;
1778             case UPDATE_HTTP_PROXY_MSG: {
1779                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                 String host = "";
1781                 String port = "";
1782                 String exclList = "";
1783                 Uri pacFileUrl = Uri.EMPTY;
1784                 if (proxy != null) {
1785                     host = proxy.getHost();
1786                     port = Integer.toString(proxy.getPort());
1787                     exclList = proxy.getExclusionListAsString();
1788                     pacFileUrl = proxy.getPacFileUrl();
1789                 }
1790                 synchronized (ActivityManagerService.this) {
1791                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                         ProcessRecord r = mLruProcesses.get(i);
1793                         if (r.thread != null) {
1794                             try {
1795                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                             } catch (RemoteException ex) {
1797                                 Slog.w(TAG, "Failed to update http proxy for: " +
1798                                         r.info.processName);
1799                             }
1800                         }
1801                     }
1802                 }
1803             } break;
1804             case PROC_START_TIMEOUT_MSG: {
1805                 if (mDidDexOpt) {
1806                     mDidDexOpt = false;
1807                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                     nmsg.obj = msg.obj;
1809                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                     return;
1811                 }
1812                 ProcessRecord app = (ProcessRecord)msg.obj;
1813                 synchronized (ActivityManagerService.this) {
1814                     processStartTimedOutLocked(app);
1815                 }
1816             } break;
1817             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                 ProcessRecord app = (ProcessRecord)msg.obj;
1819                 synchronized (ActivityManagerService.this) {
1820                     processContentProviderPublishTimedOutLocked(app);
1821                 }
1822             } break;
1823             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                 synchronized (ActivityManagerService.this) {
1825                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                 }
1827             } break;
1828             case KILL_APPLICATION_MSG: {
1829                 synchronized (ActivityManagerService.this) {
1830                     int appid = msg.arg1;
1831                     boolean restart = (msg.arg2 == 1);
1832                     Bundle bundle = (Bundle)msg.obj;
1833                     String pkg = bundle.getString("pkg");
1834                     String reason = bundle.getString("reason");
1835                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                             false, UserHandle.USER_ALL, reason);
1837                 }
1838             } break;
1839             case FINALIZE_PENDING_INTENT_MSG: {
1840                 ((PendingIntentRecord)msg.obj).completeFinalize();
1841             } break;
1842             case POST_HEAVY_NOTIFICATION_MSG: {
1843                 INotificationManager inm = NotificationManager.getService();
1844                 if (inm == null) {
1845                     return;
1846                 }
1847
1848                 ActivityRecord root = (ActivityRecord)msg.obj;
1849                 ProcessRecord process = root.app;
1850                 if (process == null) {
1851                     return;
1852                 }
1853
1854                 try {
1855                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                     String text = mContext.getString(R.string.heavy_weight_notification,
1857                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                     Notification notification = new Notification.Builder(context)
1859                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                             .setWhen(0)
1861                             .setOngoing(true)
1862                             .setTicker(text)
1863                             .setColor(mContext.getColor(
1864                                     com.android.internal.R.color.system_notification_accent_color))
1865                             .setContentTitle(text)
1866                             .setContentText(
1867                                     mContext.getText(R.string.heavy_weight_notification_detail))
1868                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                     new UserHandle(root.userId)))
1871                             .build();
1872                     try {
1873                         int[] outId = new int[1];
1874                         inm.enqueueNotificationWithTag("android", "android", null,
1875                                 R.string.heavy_weight_notification,
1876                                 notification, outId, root.userId);
1877                     } catch (RuntimeException e) {
1878                         Slog.w(ActivityManagerService.TAG,
1879                                 "Error showing notification for heavy-weight app", e);
1880                     } catch (RemoteException e) {
1881                     }
1882                 } catch (NameNotFoundException e) {
1883                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                 }
1885             } break;
1886             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                 INotificationManager inm = NotificationManager.getService();
1888                 if (inm == null) {
1889                     return;
1890                 }
1891                 try {
1892                     inm.cancelNotificationWithTag("android", null,
1893                             R.string.heavy_weight_notification,  msg.arg1);
1894                 } catch (RuntimeException e) {
1895                     Slog.w(ActivityManagerService.TAG,
1896                             "Error canceling notification for service", e);
1897                 } catch (RemoteException e) {
1898                 }
1899             } break;
1900             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                 synchronized (ActivityManagerService.this) {
1902                     checkExcessivePowerUsageLocked(true);
1903                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                 }
1907             } break;
1908             case REPORT_MEM_USAGE_MSG: {
1909                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                 Thread thread = new Thread() {
1911                     @Override public void run() {
1912                         reportMemUsage(memInfos);
1913                     }
1914                 };
1915                 thread.start();
1916                 break;
1917             }
1918             case REPORT_USER_SWITCH_MSG: {
1919                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                 break;
1921             }
1922             case CONTINUE_USER_SWITCH_MSG: {
1923                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                 break;
1925             }
1926             case USER_SWITCH_TIMEOUT_MSG: {
1927                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                 break;
1929             }
1930             case IMMERSIVE_MODE_LOCK_MSG: {
1931                 final boolean nextState = (msg.arg1 != 0);
1932                 if (mUpdateLock.isHeld() != nextState) {
1933                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                             "Applying new update lock state '" + nextState
1935                             + "' for " + (ActivityRecord)msg.obj);
1936                     if (nextState) {
1937                         mUpdateLock.acquire();
1938                     } else {
1939                         mUpdateLock.release();
1940                     }
1941                 }
1942                 break;
1943             }
1944             case PERSIST_URI_GRANTS_MSG: {
1945                 writeGrantedUriPermissions();
1946                 break;
1947             }
1948             case REQUEST_ALL_PSS_MSG: {
1949                 synchronized (ActivityManagerService.this) {
1950                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                 }
1952                 break;
1953             }
1954             case START_PROFILES_MSG: {
1955                 synchronized (ActivityManagerService.this) {
1956                     mUserController.startProfilesLocked();
1957                 }
1958                 break;
1959             }
1960             case UPDATE_TIME: {
1961                 synchronized (ActivityManagerService.this) {
1962                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                         ProcessRecord r = mLruProcesses.get(i);
1964                         if (r.thread != null) {
1965                             try {
1966                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                             } catch (RemoteException ex) {
1968                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                             }
1970                         }
1971                     }
1972                 }
1973                 break;
1974             }
1975             case SYSTEM_USER_START_MSG: {
1976                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                         Integer.toString(msg.arg1), msg.arg1);
1978                 mSystemServiceManager.startUser(msg.arg1);
1979                 break;
1980             }
1981             case SYSTEM_USER_UNLOCK_MSG: {
1982                 final int userId = msg.arg1;
1983                 mSystemServiceManager.unlockUser(userId);
1984                 synchronized (ActivityManagerService.this) {
1985                     mRecentTasks.loadUserRecentsLocked(userId);
1986                 }
1987                 if (userId == UserHandle.USER_SYSTEM) {
1988                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                 }
1990                 installEncryptionUnawareProviders(userId);
1991                 mUserController.finishUserUnlocked((UserState) msg.obj);
1992                 break;
1993             }
1994             case SYSTEM_USER_CURRENT_MSG: {
1995                 mBatteryStatsService.noteEvent(
1996                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                         Integer.toString(msg.arg2), msg.arg2);
1998                 mBatteryStatsService.noteEvent(
1999                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                         Integer.toString(msg.arg1), msg.arg1);
2001                 mSystemServiceManager.switchUser(msg.arg1);
2002                 break;
2003             }
2004             case ENTER_ANIMATION_COMPLETE_MSG: {
2005                 synchronized (ActivityManagerService.this) {
2006                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                     if (r != null && r.app != null && r.app.thread != null) {
2008                         try {
2009                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                         } catch (RemoteException e) {
2011                         }
2012                     }
2013                 }
2014                 break;
2015             }
2016             case FINISH_BOOTING_MSG: {
2017                 if (msg.arg1 != 0) {
2018                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                     finishBooting();
2020                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                 }
2022                 if (msg.arg2 != 0) {
2023                     enableScreenAfterBoot();
2024                 }
2025                 break;
2026             }
2027             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                 try {
2029                     Locale l = (Locale) msg.obj;
2030                     IBinder service = ServiceManager.getService("mount");
2031                     IMountService mountService = IMountService.Stub.asInterface(service);
2032                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                 } catch (RemoteException e) {
2035                     Log.e(TAG, "Error storing locale for decryption UI", e);
2036                 }
2037                 break;
2038             }
2039             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                 synchronized (ActivityManagerService.this) {
2041                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                         try {
2043                             // Make a one-way callback to the listener
2044                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                         } catch (RemoteException e){
2046                             // Handled by the RemoteCallbackList
2047                         }
2048                     }
2049                     mTaskStackListeners.finishBroadcast();
2050                 }
2051                 break;
2052             }
2053             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                 synchronized (ActivityManagerService.this) {
2055                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                         try {
2057                             // Make a one-way callback to the listener
2058                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                         } catch (RemoteException e){
2060                             // Handled by the RemoteCallbackList
2061                         }
2062                     }
2063                     mTaskStackListeners.finishBroadcast();
2064                 }
2065                 break;
2066             }
2067             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                 synchronized (ActivityManagerService.this) {
2069                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                         try {
2071                             // Make a one-way callback to the listener
2072                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                         } catch (RemoteException e){
2074                             // Handled by the RemoteCallbackList
2075                         }
2076                     }
2077                     mTaskStackListeners.finishBroadcast();
2078                 }
2079                 break;
2080             }
2081             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                 synchronized (ActivityManagerService.this) {
2083                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                         try {
2085                             // Make a one-way callback to the listener
2086                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                         } catch (RemoteException e){
2088                             // Handled by the RemoteCallbackList
2089                         }
2090                     }
2091                     mTaskStackListeners.finishBroadcast();
2092                 }
2093                 break;
2094             }
2095             case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                 synchronized (ActivityManagerService.this) {
2097                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                         try {
2099                             // Make a one-way callback to the listener
2100                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                     (String) msg.obj, msg.arg1);
2102                         } catch (RemoteException e){
2103                             // Handled by the RemoteCallbackList
2104                         }
2105                     }
2106                     mTaskStackListeners.finishBroadcast();
2107                 }
2108                 break;
2109             }
2110                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                     synchronized (ActivityManagerService.this) {
2112                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                             try {
2114                                 // Make a one-way callback to the listener
2115                                 mTaskStackListeners.getBroadcastItem(i)
2116                                         .onActivityDismissingDockedStack();
2117                             } catch (RemoteException e){
2118                                 // Handled by the RemoteCallbackList
2119                             }
2120                         }
2121                         mTaskStackListeners.finishBroadcast();
2122                     }
2123                     break;
2124                 }
2125             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                 final int uid = msg.arg1;
2127                 final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                 synchronized (mPidsSelfLocked) {
2130                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                         if (p.uid == uid) {
2133                             try {
2134                                 p.thread.notifyCleartextNetwork(firstPacket);
2135                             } catch (RemoteException ignored) {
2136                             }
2137                         }
2138                     }
2139                 }
2140                 break;
2141             }
2142             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                 final String procName;
2144                 final int uid;
2145                 final long memLimit;
2146                 final String reportPackage;
2147                 synchronized (ActivityManagerService.this) {
2148                     procName = mMemWatchDumpProcName;
2149                     uid = mMemWatchDumpUid;
2150                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                     if (val == null) {
2152                         val = mMemWatchProcesses.get(procName, 0);
2153                     }
2154                     if (val != null) {
2155                         memLimit = val.first;
2156                         reportPackage = val.second;
2157                     } else {
2158                         memLimit = 0;
2159                         reportPackage = null;
2160                     }
2161                 }
2162                 if (procName == null) {
2163                     return;
2164                 }
2165
2166                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                         "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                 INotificationManager inm = NotificationManager.getService();
2170                 if (inm == null) {
2171                     return;
2172                 }
2173
2174                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                 Intent deleteIntent = new Intent();
2178                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                 Intent intent = new Intent();
2180                 intent.setClassName("android", DumpHeapActivity.class.getName());
2181                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                 if (reportPackage != null) {
2184                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                 }
2186                 int userId = UserHandle.getUserId(uid);
2187                 Notification notification = new Notification.Builder(mContext)
2188                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                         .setWhen(0)
2190                         .setOngoing(true)
2191                         .setAutoCancel(true)
2192                         .setTicker(text)
2193                         .setColor(mContext.getColor(
2194                                 com.android.internal.R.color.system_notification_accent_color))
2195                         .setContentTitle(text)
2196                         .setContentText(
2197                                 mContext.getText(R.string.dump_heap_notification_detail))
2198                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                 new UserHandle(userId)))
2201                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                 deleteIntent, 0, UserHandle.SYSTEM))
2203                         .build();
2204
2205                 try {
2206                     int[] outId = new int[1];
2207                     inm.enqueueNotificationWithTag("android", "android", null,
2208                             R.string.dump_heap_notification,
2209                             notification, outId, userId);
2210                 } catch (RuntimeException e) {
2211                     Slog.w(ActivityManagerService.TAG,
2212                             "Error showing notification for dump heap", e);
2213                 } catch (RemoteException e) {
2214                 }
2215             } break;
2216             case DELETE_DUMPHEAP_MSG: {
2217                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                         DumpHeapActivity.JAVA_URI,
2219                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                         UserHandle.myUserId());
2222                 synchronized (ActivityManagerService.this) {
2223                     mMemWatchDumpFile = null;
2224                     mMemWatchDumpProcName = null;
2225                     mMemWatchDumpPid = -1;
2226                     mMemWatchDumpUid = -1;
2227                 }
2228             } break;
2229             case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231             } break;
2232             case REPORT_TIME_TRACKER_MSG: {
2233                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                 tracker.deliverResult(mContext);
2235             } break;
2236             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2238             } break;
2239             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                 try {
2242                     connection.shutdown();
2243                 } catch (RemoteException e) {
2244                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                 }
2246                 // Only a UiAutomation can set this flag and now that
2247                 // it is finished we make sure it is reset to its default.
2248                 mUserIsMonkey = false;
2249             } break;
2250             case APP_BOOST_DEACTIVATE_MSG: {
2251                 synchronized(ActivityManagerService.this) {
2252                     if (mIsBoosted) {
2253                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                             nativeMigrateFromBoost();
2255                             mIsBoosted = false;
2256                             mBoostStartTime = 0;
2257                         } else {
2258                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                         }
2261                     }
2262                 }
2263             } break;
2264             case IDLE_UIDS_MSG: {
2265                 idleUids();
2266             } break;
2267             case LOG_STACK_STATE: {
2268                 synchronized (ActivityManagerService.this) {
2269                     mStackSupervisor.logStackState();
2270                 }
2271             } break;
2272             case VR_MODE_CHANGE_MSG: {
2273                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                 final ActivityRecord r = (ActivityRecord) msg.obj;
2275                 boolean vrMode;
2276                 ComponentName requestedPackage;
2277                 ComponentName callingPackage;
2278                 int userId;
2279                 synchronized (ActivityManagerService.this) {
2280                     vrMode = r.requestedVrComponent != null;
2281                     requestedPackage = r.requestedVrComponent;
2282                     userId = r.userId;
2283                     callingPackage = r.info.getComponentName();
2284                     if (mInVrMode != vrMode) {
2285                         mInVrMode = vrMode;
2286                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                     }
2288                 }
2289                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290             } break;
2291             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                 final ActivityRecord r = (ActivityRecord) msg.obj;
2293                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                 if (needsVrMode) {
2295                     VrManagerInternal vrService =
2296                             LocalServices.getService(VrManagerInternal.class);
2297                     boolean enable = msg.arg1 == 1;
2298                     vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2299                             r.info.getComponentName());
2300                 }
2301             } break;
2302             }
2303         }
2304     };
2305
2306     static final int COLLECT_PSS_BG_MSG = 1;
2307
2308     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2309         @Override
2310         public void handleMessage(Message msg) {
2311             switch (msg.what) {
2312             case COLLECT_PSS_BG_MSG: {
2313                 long start = SystemClock.uptimeMillis();
2314                 MemInfoReader memInfo = null;
2315                 synchronized (ActivityManagerService.this) {
2316                     if (mFullPssPending) {
2317                         mFullPssPending = false;
2318                         memInfo = new MemInfoReader();
2319                     }
2320                 }
2321                 if (memInfo != null) {
2322                     updateCpuStatsNow();
2323                     long nativeTotalPss = 0;
2324                     synchronized (mProcessCpuTracker) {
2325                         final int N = mProcessCpuTracker.countStats();
2326                         for (int j=0; j<N; j++) {
2327                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2328                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2329                                 // This is definitely an application process; skip it.
2330                                 continue;
2331                             }
2332                             synchronized (mPidsSelfLocked) {
2333                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2334                                     // This is one of our own processes; skip it.
2335                                     continue;
2336                                 }
2337                             }
2338                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2339                         }
2340                     }
2341                     memInfo.readMemInfo();
2342                     synchronized (ActivityManagerService.this) {
2343                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2344                                 + (SystemClock.uptimeMillis()-start) + "ms");
2345                         final long cachedKb = memInfo.getCachedSizeKb();
2346                         final long freeKb = memInfo.getFreeSizeKb();
2347                         final long zramKb = memInfo.getZramTotalSizeKb();
2348                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2349                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2350                                 kernelKb*1024, nativeTotalPss*1024);
2351                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2352                                 nativeTotalPss);
2353                     }
2354                 }
2355
2356                 int num = 0;
2357                 long[] tmp = new long[2];
2358                 do {
2359                     ProcessRecord proc;
2360                     int procState;
2361                     int pid;
2362                     long lastPssTime;
2363                     synchronized (ActivityManagerService.this) {
2364                         if (mPendingPssProcesses.size() <= 0) {
2365                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2366                                     "Collected PSS of " + num + " processes in "
2367                                     + (SystemClock.uptimeMillis() - start) + "ms");
2368                             mPendingPssProcesses.clear();
2369                             return;
2370                         }
2371                         proc = mPendingPssProcesses.remove(0);
2372                         procState = proc.pssProcState;
2373                         lastPssTime = proc.lastPssTime;
2374                         if (proc.thread != null && procState == proc.setProcState
2375                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2376                                         < SystemClock.uptimeMillis()) {
2377                             pid = proc.pid;
2378                         } else {
2379                             proc = null;
2380                             pid = 0;
2381                         }
2382                     }
2383                     if (proc != null) {
2384                         long pss = Debug.getPss(pid, tmp, null);
2385                         synchronized (ActivityManagerService.this) {
2386                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2387                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2388                                 num++;
2389                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2390                                         SystemClock.uptimeMillis());
2391                             }
2392                         }
2393                     }
2394                 } while (true);
2395             }
2396             }
2397         }
2398     };
2399
2400     public void setSystemProcess() {
2401         try {
2402             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2403             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2404             ServiceManager.addService("meminfo", new MemBinder(this));
2405             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2406             ServiceManager.addService("dbinfo", new DbBinder(this));
2407             if (MONITOR_CPU_USAGE) {
2408                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2409             }
2410             ServiceManager.addService("permission", new PermissionController(this));
2411             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2412
2413             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2414                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2415             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2416
2417             synchronized (this) {
2418                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2419                 app.persistent = true;
2420                 app.pid = MY_PID;
2421                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2422                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2423                 synchronized (mPidsSelfLocked) {
2424                     mPidsSelfLocked.put(app.pid, app);
2425                 }
2426                 updateLruProcessLocked(app, false, null);
2427                 updateOomAdjLocked();
2428             }
2429         } catch (PackageManager.NameNotFoundException e) {
2430             throw new RuntimeException(
2431                     "Unable to find android system package", e);
2432         }
2433     }
2434
2435     public void setWindowManager(WindowManagerService wm) {
2436         mWindowManager = wm;
2437         mStackSupervisor.setWindowManager(wm);
2438         mActivityStarter.setWindowManager(wm);
2439     }
2440
2441     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2442         mUsageStatsService = usageStatsManager;
2443     }
2444
2445     public void startObservingNativeCrashes() {
2446         final NativeCrashListener ncl = new NativeCrashListener(this);
2447         ncl.start();
2448     }
2449
2450     public IAppOpsService getAppOpsService() {
2451         return mAppOpsService;
2452     }
2453
2454     static class MemBinder extends Binder {
2455         ActivityManagerService mActivityManagerService;
2456         MemBinder(ActivityManagerService activityManagerService) {
2457             mActivityManagerService = activityManagerService;
2458         }
2459
2460         @Override
2461         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                     != PackageManager.PERMISSION_GRANTED) {
2464                 pw.println("Permission Denial: can't dump meminfo from from pid="
2465                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                         + " without permission " + android.Manifest.permission.DUMP);
2467                 return;
2468             }
2469
2470             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2471         }
2472     }
2473
2474     static class GraphicsBinder extends Binder {
2475         ActivityManagerService mActivityManagerService;
2476         GraphicsBinder(ActivityManagerService activityManagerService) {
2477             mActivityManagerService = activityManagerService;
2478         }
2479
2480         @Override
2481         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                     != PackageManager.PERMISSION_GRANTED) {
2484                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2485                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                         + " without permission " + android.Manifest.permission.DUMP);
2487                 return;
2488             }
2489
2490             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2491         }
2492     }
2493
2494     static class DbBinder extends Binder {
2495         ActivityManagerService mActivityManagerService;
2496         DbBinder(ActivityManagerService activityManagerService) {
2497             mActivityManagerService = activityManagerService;
2498         }
2499
2500         @Override
2501         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                     != PackageManager.PERMISSION_GRANTED) {
2504                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2505                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                         + " without permission " + android.Manifest.permission.DUMP);
2507                 return;
2508             }
2509
2510             mActivityManagerService.dumpDbInfo(fd, pw, args);
2511         }
2512     }
2513
2514     static class CpuBinder extends Binder {
2515         ActivityManagerService mActivityManagerService;
2516         CpuBinder(ActivityManagerService activityManagerService) {
2517             mActivityManagerService = activityManagerService;
2518         }
2519
2520         @Override
2521         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                     != PackageManager.PERMISSION_GRANTED) {
2524                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2525                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                         + " without permission " + android.Manifest.permission.DUMP);
2527                 return;
2528             }
2529
2530             synchronized (mActivityManagerService.mProcessCpuTracker) {
2531                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2532                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2533                         SystemClock.uptimeMillis()));
2534             }
2535         }
2536     }
2537
2538     public static final class Lifecycle extends SystemService {
2539         private final ActivityManagerService mService;
2540
2541         public Lifecycle(Context context) {
2542             super(context);
2543             mService = new ActivityManagerService(context);
2544         }
2545
2546         @Override
2547         public void onStart() {
2548             mService.start();
2549         }
2550
2551         public ActivityManagerService getService() {
2552             return mService;
2553         }
2554     }
2555
2556     // Note: This method is invoked on the main thread but may need to attach various
2557     // handlers to other threads.  So take care to be explicit about the looper.
2558     public ActivityManagerService(Context systemContext) {
2559         mContext = systemContext;
2560         mFactoryTest = FactoryTest.getMode();
2561         mSystemThread = ActivityThread.currentActivityThread();
2562
2563         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2564
2565         mHandlerThread = new ServiceThread(TAG,
2566                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2567         mHandlerThread.start();
2568         mHandler = new MainHandler(mHandlerThread.getLooper());
2569         mUiHandler = new UiHandler();
2570
2571         /* static; one-time init here */
2572         if (sKillHandler == null) {
2573             sKillThread = new ServiceThread(TAG + ":kill",
2574                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2575             sKillThread.start();
2576             sKillHandler = new KillHandler(sKillThread.getLooper());
2577         }
2578
2579         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580                 "foreground", BROADCAST_FG_TIMEOUT, false);
2581         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2582                 "background", BROADCAST_BG_TIMEOUT, true);
2583         mBroadcastQueues[0] = mFgBroadcastQueue;
2584         mBroadcastQueues[1] = mBgBroadcastQueue;
2585
2586         mServices = new ActiveServices(this);
2587         mProviderMap = new ProviderMap(this);
2588         mAppErrors = new AppErrors(mContext, this);
2589
2590         // TODO: Move creation of battery stats service outside of activity manager service.
2591         File dataDir = Environment.getDataDirectory();
2592         File systemDir = new File(dataDir, "system");
2593         systemDir.mkdirs();
2594         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2595         mBatteryStatsService.getActiveStatistics().readLocked();
2596         mBatteryStatsService.scheduleWriteToDisk();
2597         mOnBattery = DEBUG_POWER ? true
2598                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2599         mBatteryStatsService.getActiveStatistics().setCallback(this);
2600
2601         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2602
2603         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2604         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2605                 new IAppOpsCallback.Stub() {
2606                     @Override public void opChanged(int op, int uid, String packageName) {
2607                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2608                             if (mAppOpsService.checkOperation(op, uid, packageName)
2609                                     != AppOpsManager.MODE_ALLOWED) {
2610                                 runInBackgroundDisabled(uid);
2611                             }
2612                         }
2613                     }
2614                 });
2615
2616         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2617
2618         mUserController = new UserController(this);
2619
2620         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2621             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2622
2623         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2624
2625         mConfiguration.setToDefaults();
2626         mConfiguration.setLocales(LocaleList.getDefault());
2627
2628         mConfigurationSeq = mConfiguration.seq = 1;
2629         mProcessCpuTracker.init();
2630
2631         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2632         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2633         mStackSupervisor = new ActivityStackSupervisor(this);
2634         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637         mProcessCpuThread = new Thread("CpuTracker") {
2638             @Override
2639             public void run() {
2640                 while (true) {
2641                     try {
2642                         try {
2643                             synchronized(this) {
2644                                 final long now = SystemClock.uptimeMillis();
2645                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                 //        + ", write delay=" + nextWriteDelay);
2649                                 if (nextWriteDelay < nextCpuDelay) {
2650                                     nextCpuDelay = nextWriteDelay;
2651                                 }
2652                                 if (nextCpuDelay > 0) {
2653                                     mProcessCpuMutexFree.set(true);
2654                                     this.wait(nextCpuDelay);
2655                                 }
2656                             }
2657                         } catch (InterruptedException e) {
2658                         }
2659                         updateCpuStatsNow();
2660                     } catch (Exception e) {
2661                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                     }
2663                 }
2664             }
2665         };
2666
2667         Watchdog.getInstance().addMonitor(this);
2668         Watchdog.getInstance().addThread(mHandler);
2669     }
2670
2671     public void setSystemServiceManager(SystemServiceManager mgr) {
2672         mSystemServiceManager = mgr;
2673     }
2674
2675     public void setInstaller(Installer installer) {
2676         mInstaller = installer;
2677     }
2678
2679     private void start() {
2680         Process.removeAllProcessGroups();
2681         mProcessCpuThread.start();
2682
2683         mBatteryStatsService.publish(mContext);
2684         mAppOpsService.publish(mContext);
2685         Slog.d("AppOps", "AppOpsService published");
2686         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687     }
2688
2689     void onUserStoppedLocked(int userId) {
2690         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691     }
2692
2693     public void initPowerManagement() {
2694         mStackSupervisor.initPowerManagement();
2695         mBatteryStatsService.initPowerManagement();
2696         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699         mVoiceWakeLock.setReferenceCounted(false);
2700     }
2701
2702     @Override
2703     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704             throws RemoteException {
2705         if (code == SYSPROPS_TRANSACTION) {
2706             // We need to tell all apps about the system property change.
2707             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708             synchronized(this) {
2709                 final int NP = mProcessNames.getMap().size();
2710                 for (int ip=0; ip<NP; ip++) {
2711                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                     final int NA = apps.size();
2713                     for (int ia=0; ia<NA; ia++) {
2714                         ProcessRecord app = apps.valueAt(ia);
2715                         if (app.thread != null) {
2716                             procs.add(app.thread.asBinder());
2717                         }
2718                     }
2719                 }
2720             }
2721
2722             int N = procs.size();
2723             for (int i=0; i<N; i++) {
2724                 Parcel data2 = Parcel.obtain();
2725                 try {
2726                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                 } catch (RemoteException e) {
2728                 }
2729                 data2.recycle();
2730             }
2731         }
2732         try {
2733             return super.onTransact(code, data, reply, flags);
2734         } catch (RuntimeException e) {
2735             // The activity manager only throws security exceptions, so let's
2736             // log all others.
2737             if (!(e instanceof SecurityException)) {
2738                 Slog.wtf(TAG, "Activity Manager Crash", e);
2739             }
2740             throw e;
2741         }
2742     }
2743
2744     void updateCpuStats() {
2745         final long now = SystemClock.uptimeMillis();
2746         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747             return;
2748         }
2749         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750             synchronized (mProcessCpuThread) {
2751                 mProcessCpuThread.notify();
2752             }
2753         }
2754     }
2755
2756     void updateCpuStatsNow() {
2757         synchronized (mProcessCpuTracker) {
2758             mProcessCpuMutexFree.set(false);
2759             final long now = SystemClock.uptimeMillis();
2760             boolean haveNewCpuStats = false;
2761
2762             if (MONITOR_CPU_USAGE &&
2763                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                 mLastCpuTime.set(now);
2765                 mProcessCpuTracker.update();
2766                 if (mProcessCpuTracker.hasGoodLastStats()) {
2767                     haveNewCpuStats = true;
2768                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                     //Slog.i(TAG, "Total CPU usage: "
2770                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                     // Slog the cpu usage if the property is set.
2773                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                         int user = mProcessCpuTracker.getLastUserTime();
2775                         int system = mProcessCpuTracker.getLastSystemTime();
2776                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                         int irq = mProcessCpuTracker.getLastIrqTime();
2778                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                         int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                         int total = user + system + iowait + irq + softIrq + idle;
2782                         if (total == 0) total = 1;
2783
2784                         EventLog.writeEvent(EventLogTags.CPU,
2785                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                 (user * 100) / total,
2787                                 (system * 100) / total,
2788                                 (iowait * 100) / total,
2789                                 (irq * 100) / total,
2790                                 (softIrq * 100) / total);
2791                     }
2792                 }
2793             }
2794
2795             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796             synchronized(bstats) {
2797                 synchronized(mPidsSelfLocked) {
2798                     if (haveNewCpuStats) {
2799                         if (bstats.startAddingCpuLocked()) {
2800                             int totalUTime = 0;
2801                             int totalSTime = 0;
2802                             final int N = mProcessCpuTracker.countStats();
2803                             for (int i=0; i<N; i++) {
2804                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                 if (!st.working) {
2806                                     continue;
2807                                 }
2808                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                 totalUTime += st.rel_utime;
2810                                 totalSTime += st.rel_stime;
2811                                 if (pr != null) {
2812                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                     if (ps == null || !ps.isActive()) {
2814                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                 pr.info.uid, pr.processName);
2816                                     }
2817                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                 } else {
2820                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                     if (ps == null || !ps.isActive()) {
2822                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                 bstats.mapUid(st.uid), st.name);
2824                                     }
2825                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                 }
2827                             }
2828                             final int userTime = mProcessCpuTracker.getLastUserTime();
2829                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                         }
2837                     }
2838                 }
2839
2840                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                     mLastWriteTime = now;
2842                     mBatteryStatsService.scheduleWriteToDisk();
2843                 }
2844             }
2845         }
2846     }
2847
2848     @Override
2849     public void batteryNeedsCpuUpdate() {
2850         updateCpuStatsNow();
2851     }
2852
2853     @Override
2854     public void batteryPowerChanged(boolean onBattery) {
2855         // When plugging in, update the CPU stats first before changing
2856         // the plug state.
2857         updateCpuStatsNow();
2858         synchronized (this) {
2859             synchronized(mPidsSelfLocked) {
2860                 mOnBattery = DEBUG_POWER ? true : onBattery;
2861             }
2862         }
2863     }
2864
2865     @Override
2866     public void batterySendBroadcast(Intent intent) {
2867         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                 AppOpsManager.OP_NONE, null, false, false,
2869                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870     }
2871
2872     /**
2873      * Initialize the application bind args. These are passed to each
2874      * process when the bindApplication() IPC is sent to the process. They're
2875      * lazily setup to make sure the services are running when they're asked for.
2876      */
2877     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878         if (mAppBindArgs == null) {
2879             mAppBindArgs = new HashMap<>();
2880
2881             // Isolated processes won't get this optimization, so that we don't
2882             // violate the rules about which services they have access to.
2883             if (!isolated) {
2884                 // Setup the application init args
2885                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2886                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2887                 mAppBindArgs.put(Context.ALARM_SERVICE,
2888                         ServiceManager.getService(Context.ALARM_SERVICE));
2889             }
2890         }
2891         return mAppBindArgs;
2892     }
2893
2894     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2895         if (r == null || mFocusedActivity == r) {
2896             return false;
2897         }
2898
2899         if (!r.isFocusable()) {
2900             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2901             return false;
2902         }
2903
2904         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2905
2906         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2907         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2908                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2909         mDoingSetFocusedActivity = true;
2910
2911         final ActivityRecord last = mFocusedActivity;
2912         mFocusedActivity = r;
2913         if (r.task.isApplicationTask()) {
2914             if (mCurAppTimeTracker != r.appTimeTracker) {
2915                 // We are switching app tracking.  Complete the current one.
2916                 if (mCurAppTimeTracker != null) {
2917                     mCurAppTimeTracker.stop();
2918                     mHandler.obtainMessage(
2919                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2920                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2921                     mCurAppTimeTracker = null;
2922                 }
2923                 if (r.appTimeTracker != null) {
2924                     mCurAppTimeTracker = r.appTimeTracker;
2925                     startTimeTrackingFocusedActivityLocked();
2926                 }
2927             } else {
2928                 startTimeTrackingFocusedActivityLocked();
2929             }
2930         } else {
2931             r.appTimeTracker = null;
2932         }
2933         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2934         // TODO: Probably not, because we don't want to resume voice on switching
2935         // back to this activity
2936         if (r.task.voiceInteractor != null) {
2937             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2938         } else {
2939             finishRunningVoiceLocked();
2940             IVoiceInteractionSession session;
2941             if (last != null && ((session = last.task.voiceSession) != null
2942                     || (session = last.voiceSession) != null)) {
2943                 // We had been in a voice interaction session, but now focused has
2944                 // move to something different.  Just finish the session, we can't
2945                 // return to it and retain the proper state and synchronization with
2946                 // the voice interaction service.
2947                 finishVoiceTask(session);
2948             }
2949         }
2950         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2951             mWindowManager.setFocusedApp(r.appToken, true);
2952         }
2953         applyUpdateLockStateLocked(r);
2954         applyUpdateVrModeLocked(r);
2955         if (mFocusedActivity.userId != mLastFocusedUserId) {
2956             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2957             mHandler.obtainMessage(
2958                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2959             mLastFocusedUserId = mFocusedActivity.userId;
2960         }
2961
2962         // Log a warning if the focused app is changed during the process. This could
2963         // indicate a problem of the focus setting logic!
2964         if (mFocusedActivity != r) Slog.w(TAG,
2965                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2966         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2967
2968         EventLogTags.writeAmFocusedActivity(
2969                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2970                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2971                 reason);
2972         return true;
2973     }
2974
2975     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2976         if (mFocusedActivity != goingAway) {
2977             return;
2978         }
2979
2980         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2981         if (focusedStack != null) {
2982             final ActivityRecord top = focusedStack.topActivity();
2983             if (top != null && top.userId != mLastFocusedUserId) {
2984                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2985                 mHandler.sendMessage(
2986                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2987                 mLastFocusedUserId = top.userId;
2988             }
2989         }
2990
2991         // Try to move focus to another activity if possible.
2992         if (setFocusedActivityLocked(
2993                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2994             return;
2995         }
2996
2997         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2998                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2999         mFocusedActivity = null;
3000         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3001     }
3002
3003     @Override
3004     public void setFocusedStack(int stackId) {
3005         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3006         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3007         final long callingId = Binder.clearCallingIdentity();
3008         try {
3009             synchronized (this) {
3010                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3011                 if (stack == null) {
3012                     return;
3013                 }
3014                 final ActivityRecord r = stack.topRunningActivityLocked();
3015                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3016                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3017                 }
3018             }
3019         } finally {
3020             Binder.restoreCallingIdentity(callingId);
3021         }
3022     }
3023
3024     @Override
3025     public void setFocusedTask(int taskId) {
3026         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3027         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3028         final long callingId = Binder.clearCallingIdentity();
3029         try {
3030             synchronized (this) {
3031                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3032                 if (task == null) {
3033                     return;
3034                 }
3035                 final ActivityRecord r = task.topRunningActivityLocked();
3036                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3037                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3038                 }
3039             }
3040         } finally {
3041             Binder.restoreCallingIdentity(callingId);
3042         }
3043     }
3044
3045     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3046     @Override
3047     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3048         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3049         synchronized (this) {
3050             if (listener != null) {
3051                 mTaskStackListeners.register(listener);
3052             }
3053         }
3054     }
3055
3056     @Override
3057     public void notifyActivityDrawn(IBinder token) {
3058         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3059         synchronized (this) {
3060             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3061             if (r != null) {
3062                 r.task.stack.notifyActivityDrawnLocked(r);
3063             }
3064         }
3065     }
3066
3067     final void applyUpdateLockStateLocked(ActivityRecord r) {
3068         // Modifications to the UpdateLock state are done on our handler, outside
3069         // the activity manager's locks.  The new state is determined based on the
3070         // state *now* of the relevant activity record.  The object is passed to
3071         // the handler solely for logging detail, not to be consulted/modified.
3072         final boolean nextState = r != null && r.immersive;
3073         mHandler.sendMessage(
3074                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3075     }
3076
3077     final void applyUpdateVrModeLocked(ActivityRecord r) {
3078         mHandler.sendMessage(
3079                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3080     }
3081
3082     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3083         mHandler.sendMessage(
3084                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3085     }
3086
3087     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3088         Message msg = Message.obtain();
3089         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3090         msg.obj = r.task.askedCompatMode ? null : r;
3091         mUiHandler.sendMessage(msg);
3092     }
3093
3094     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3095             String what, Object obj, ProcessRecord srcApp) {
3096         app.lastActivityTime = now;
3097
3098         if (app.activities.size() > 0) {
3099             // Don't want to touch dependent processes that are hosting activities.
3100             return index;
3101         }
3102
3103         int lrui = mLruProcesses.lastIndexOf(app);
3104         if (lrui < 0) {
3105             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3106                     + what + " " + obj + " from " + srcApp);
3107             return index;
3108         }
3109
3110         if (lrui >= index) {
3111             // Don't want to cause this to move dependent processes *back* in the
3112             // list as if they were less frequently used.
3113             return index;
3114         }
3115
3116         if (lrui >= mLruProcessActivityStart) {
3117             // Don't want to touch dependent processes that are hosting activities.
3118             return index;
3119         }
3120
3121         mLruProcesses.remove(lrui);
3122         if (index > 0) {
3123             index--;
3124         }
3125         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3126                 + " in LRU list: " + app);
3127         mLruProcesses.add(index, app);
3128         return index;
3129     }
3130
3131     static void killProcessGroup(int uid, int pid) {
3132         if (sKillHandler != null) {
3133             sKillHandler.sendMessage(
3134                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3135         } else {
3136             Slog.w(TAG, "Asked to kill process group before system bringup!");
3137             Process.killProcessGroup(uid, pid);
3138         }
3139     }
3140
3141     final void removeLruProcessLocked(ProcessRecord app) {
3142         int lrui = mLruProcesses.lastIndexOf(app);
3143         if (lrui >= 0) {
3144             if (!app.killed) {
3145                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3146                 Process.killProcessQuiet(app.pid);
3147                 killProcessGroup(app.uid, app.pid);
3148             }
3149             if (lrui <= mLruProcessActivityStart) {
3150                 mLruProcessActivityStart--;
3151             }
3152             if (lrui <= mLruProcessServiceStart) {
3153                 mLruProcessServiceStart--;
3154             }
3155             mLruProcesses.remove(lrui);
3156         }
3157     }
3158
3159     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3160             ProcessRecord client) {
3161         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3162                 || app.treatLikeActivity;
3163         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3164         if (!activityChange && hasActivity) {
3165             // The process has activities, so we are only allowing activity-based adjustments
3166             // to move it.  It should be kept in the front of the list with other
3167             // processes that have activities, and we don't want those to change their
3168             // order except due to activity operations.
3169             return;
3170         }
3171
3172         mLruSeq++;
3173         final long now = SystemClock.uptimeMillis();
3174         app.lastActivityTime = now;
3175
3176         // First a quick reject: if the app is already at the position we will
3177         // put it, then there is nothing to do.
3178         if (hasActivity) {
3179             final int N = mLruProcesses.size();
3180             if (N > 0 && mLruProcesses.get(N-1) == app) {
3181                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3182                 return;
3183             }
3184         } else {
3185             if (mLruProcessServiceStart > 0
3186                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3187                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3188                 return;
3189             }
3190         }
3191
3192         int lrui = mLruProcesses.lastIndexOf(app);
3193
3194         if (app.persistent && lrui >= 0) {
3195             // We don't care about the position of persistent processes, as long as
3196             // they are in the list.
3197             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3198             return;
3199         }
3200
3201         /* In progress: compute new position first, so we can avoid doing work
3202            if the process is not actually going to move.  Not yet working.
3203         int addIndex;
3204         int nextIndex;
3205         boolean inActivity = false, inService = false;
3206         if (hasActivity) {
3207             // Process has activities, put it at the very tipsy-top.
3208             addIndex = mLruProcesses.size();
3209             nextIndex = mLruProcessServiceStart;
3210             inActivity = true;
3211         } else if (hasService) {
3212             // Process has services, put it at the top of the service list.
3213             addIndex = mLruProcessActivityStart;
3214             nextIndex = mLruProcessServiceStart;
3215             inActivity = true;
3216             inService = true;
3217         } else  {
3218             // Process not otherwise of interest, it goes to the top of the non-service area.
3219             addIndex = mLruProcessServiceStart;
3220             if (client != null) {
3221                 int clientIndex = mLruProcesses.lastIndexOf(client);
3222                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3223                         + app);
3224                 if (clientIndex >= 0 && addIndex > clientIndex) {
3225                     addIndex = clientIndex;
3226                 }
3227             }
3228             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3229         }
3230
3231         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3232                 + mLruProcessActivityStart + "): " + app);
3233         */
3234
3235         if (lrui >= 0) {
3236             if (lrui < mLruProcessActivityStart) {
3237                 mLruProcessActivityStart--;
3238             }
3239             if (lrui < mLruProcessServiceStart) {
3240                 mLruProcessServiceStart--;
3241             }
3242             /*
3243             if (addIndex > lrui) {
3244                 addIndex--;
3245             }
3246             if (nextIndex > lrui) {
3247                 nextIndex--;
3248             }
3249             */
3250             mLruProcesses.remove(lrui);
3251         }
3252
3253         /*
3254         mLruProcesses.add(addIndex, app);
3255         if (inActivity) {
3256             mLruProcessActivityStart++;
3257         }
3258         if (inService) {
3259             mLruProcessActivityStart++;
3260         }
3261         */
3262
3263         int nextIndex;
3264         if (hasActivity) {
3265             final int N = mLruProcesses.size();
3266             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3267                 // Process doesn't have activities, but has clients with
3268                 // activities...  move it up, but one below the top (the top
3269                 // should always have a real activity).
3270                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3271                         "Adding to second-top of LRU activity list: " + app);
3272                 mLruProcesses.add(N - 1, app);
3273                 // To keep it from spamming the LRU list (by making a bunch of clients),
3274                 // we will push down any other entries owned by the app.
3275                 final int uid = app.info.uid;
3276                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3277                     ProcessRecord subProc = mLruProcesses.get(i);
3278                     if (subProc.info.uid == uid) {
3279                         // We want to push this one down the list.  If the process after
3280                         // it is for the same uid, however, don't do so, because we don't
3281                         // want them internally to be re-ordered.
3282                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3283                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3284                                     "Pushing uid " + uid + " swapping at " + i + ": "
3285                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3286                             ProcessRecord tmp = mLruProcesses.get(i);
3287                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3288                             mLruProcesses.set(i - 1, tmp);
3289                             i--;
3290                         }
3291                     } else {
3292                         // A gap, we can stop here.
3293                         break;
3294                     }
3295                 }
3296             } else {
3297                 // Process has activities, put it at the very tipsy-top.
3298                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3299                 mLruProcesses.add(app);
3300             }
3301             nextIndex = mLruProcessServiceStart;
3302         } else if (hasService) {
3303             // Process has services, put it at the top of the service list.
3304             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3305             mLruProcesses.add(mLruProcessActivityStart, app);
3306             nextIndex = mLruProcessServiceStart;
3307             mLruProcessActivityStart++;
3308         } else  {
3309             // Process not otherwise of interest, it goes to the top of the non-service area.
3310             int index = mLruProcessServiceStart;
3311             if (client != null) {
3312                 // If there is a client, don't allow the process to be moved up higher
3313                 // in the list than that client.
3314                 int clientIndex = mLruProcesses.lastIndexOf(client);
3315                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3316                         + " when updating " + app);
3317                 if (clientIndex <= lrui) {
3318                     // Don't allow the client index restriction to push it down farther in the
3319                     // list than it already is.
3320                     clientIndex = lrui;
3321                 }
3322                 if (clientIndex >= 0 && index > clientIndex) {
3323                     index = clientIndex;
3324                 }
3325             }
3326             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3327             mLruProcesses.add(index, app);
3328             nextIndex = index-1;
3329             mLruProcessActivityStart++;
3330             mLruProcessServiceStart++;
3331         }
3332
3333         // If the app is currently using a content provider or service,
3334         // bump those processes as well.
3335         for (int j=app.connections.size()-1; j>=0; j--) {
3336             ConnectionRecord cr = app.connections.valueAt(j);
3337             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3338                     && cr.binding.service.app != null
3339                     && cr.binding.service.app.lruSeq != mLruSeq
3340                     && !cr.binding.service.app.persistent) {
3341                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3342                         "service connection", cr, app);
3343             }
3344         }
3345         for (int j=app.conProviders.size()-1; j>=0; j--) {
3346             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3347             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3348                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3349                         "provider reference", cpr, app);
3350             }
3351         }
3352     }
3353
3354     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3355         if (uid == Process.SYSTEM_UID) {
3356             // The system gets to run in any process.  If there are multiple
3357             // processes with the same uid, just pick the first (this
3358             // should never happen).
3359             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3360             if (procs == null) return null;
3361             final int procCount = procs.size();
3362             for (int i = 0; i < procCount; i++) {
3363                 final int procUid = procs.keyAt(i);
3364                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3365                     // Don't use an app process or different user process for system component.
3366                     continue;
3367                 }
3368                 return procs.valueAt(i);
3369             }
3370         }
3371         ProcessRecord proc = mProcessNames.get(processName, uid);
3372         if (false && proc != null && !keepIfLarge
3373                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3374                 && proc.lastCachedPss >= 4000) {
3375             // Turn this condition on to cause killing to happen regularly, for testing.
3376             if (proc.baseProcessTracker != null) {
3377                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3378             }
3379             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3380         } else if (proc != null && !keepIfLarge
3381                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3382                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3383             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3384             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3385                 if (proc.baseProcessTracker != null) {
3386                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3387                 }
3388                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3389             }
3390         }
3391         return proc;
3392     }
3393
3394     void notifyPackageUse(String packageName, int reason) {
3395         IPackageManager pm = AppGlobals.getPackageManager();
3396         try {
3397             pm.notifyPackageUse(packageName, reason);
3398         } catch (RemoteException e) {
3399         }
3400     }
3401
3402     boolean isNextTransitionForward() {
3403         int transit = mWindowManager.getPendingAppTransition();
3404         return transit == TRANSIT_ACTIVITY_OPEN
3405                 || transit == TRANSIT_TASK_OPEN
3406                 || transit == TRANSIT_TASK_TO_FRONT;
3407     }
3408
3409     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3410             String processName, String abiOverride, int uid, Runnable crashHandler) {
3411         synchronized(this) {
3412             ApplicationInfo info = new ApplicationInfo();
3413             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3414             // For isolated processes, the former contains the parent's uid and the latter the
3415             // actual uid of the isolated process.
3416             // In the special case introduced by this method (which is, starting an isolated
3417             // process directly from the SystemServer without an actual parent app process) the
3418             // closest thing to a parent's uid is SYSTEM_UID.
3419             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3420             // the |isolated| logic in the ProcessRecord constructor.
3421             info.uid = Process.SYSTEM_UID;
3422             info.processName = processName;
3423             info.className = entryPoint;
3424             info.packageName = "android";
3425             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3426                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3427                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3428                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3429                     crashHandler);
3430             return proc != null ? proc.pid : 0;
3431         }
3432     }
3433
3434     final ProcessRecord startProcessLocked(String processName,
3435             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3436             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3437             boolean isolated, boolean keepIfLarge) {
3438         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3439                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3440                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3441                 null /* crashHandler */);
3442     }
3443
3444     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3445             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3446             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3447             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3448         long startTime = SystemClock.elapsedRealtime();
3449         ProcessRecord app;
3450         if (!isolated) {
3451             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3452             checkTime(startTime, "startProcess: after getProcessRecord");
3453
3454             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3455                 // If we are in the background, then check to see if this process
3456                 // is bad.  If so, we will just silently fail.
3457                 if (mAppErrors.isBadProcessLocked(info)) {
3458                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3459                             + "/" + info.processName);
3460                     return null;
3461                 }
3462             } else {
3463                 // When the user is explicitly starting a process, then clear its
3464                 // crash count so that we won't make it bad until they see at
3465                 // least one crash dialog again, and make the process good again
3466                 // if it had been bad.
3467                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3468                         + "/" + info.processName);
3469                 mAppErrors.resetProcessCrashTimeLocked(info);
3470                 if (mAppErrors.isBadProcessLocked(info)) {
3471                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3472                             UserHandle.getUserId(info.uid), info.uid,
3473                             info.processName);
3474                     mAppErrors.clearBadProcessLocked(info);
3475                     if (app != null) {
3476                         app.bad = false;
3477                     }
3478                 }
3479             }
3480         } else {
3481             // If this is an isolated process, it can't re-use an existing process.
3482             app = null;
3483         }
3484
3485         // app launch boost for big.little configurations
3486         // use cpusets to migrate freshly launched tasks to big cores
3487         synchronized(ActivityManagerService.this) {
3488             nativeMigrateToBoost();
3489             mIsBoosted = true;
3490             mBoostStartTime = SystemClock.uptimeMillis();
3491             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3492             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3493         }
3494
3495         // We don't have to do anything more if:
3496         // (1) There is an existing application record; and
3497         // (2) The caller doesn't think it is dead, OR there is no thread
3498         //     object attached to it so we know it couldn't have crashed; and
3499         // (3) There is a pid assigned to it, so it is either starting or
3500         //     already running.
3501         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3502                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3503                 + " thread=" + (app != null ? app.thread : null)
3504                 + " pid=" + (app != null ? app.pid : -1));
3505         if (app != null && app.pid > 0) {
3506             if (!knownToBeDead || app.thread == null) {
3507                 // We already have the app running, or are waiting for it to
3508                 // come up (we have a pid but not yet its thread), so keep it.
3509                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3510                 // If this is a new package in the process, add the package to the list
3511                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3512                 checkTime(startTime, "startProcess: done, added package to proc");
3513                 return app;
3514             }
3515
3516             // An application record is attached to a previous process,
3517             // clean it up now.
3518             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3519             checkTime(startTime, "startProcess: bad proc running, killing");
3520             killProcessGroup(app.uid, app.pid);
3521             handleAppDiedLocked(app, true, true);
3522             checkTime(startTime, "startProcess: done killing old proc");
3523         }
3524
3525         String hostingNameStr = hostingName != null
3526                 ? hostingName.flattenToShortString() : null;
3527
3528         if (app == null) {
3529             checkTime(startTime, "startProcess: creating new process record");
3530             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3531             if (app == null) {
3532                 Slog.w(TAG, "Failed making new process record for "
3533                         + processName + "/" + info.uid + " isolated=" + isolated);
3534                 return null;
3535             }
3536             app.crashHandler = crashHandler;
3537             checkTime(startTime, "startProcess: done creating new process record");
3538         } else {
3539             // If this is a new package in the process, add the package to the list
3540             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3541             checkTime(startTime, "startProcess: added package to existing proc");
3542         }
3543
3544         // If the system is not ready yet, then hold off on starting this
3545         // process until it is.
3546         if (!mProcessesReady
3547                 && !isAllowedWhileBooting(info)
3548                 && !allowWhileBooting) {
3549             if (!mProcessesOnHold.contains(app)) {
3550                 mProcessesOnHold.add(app);
3551             }
3552             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3553                     "System not ready, putting on hold: " + app);
3554             checkTime(startTime, "startProcess: returning with proc on hold");
3555             return app;
3556         }
3557
3558         checkTime(startTime, "startProcess: stepping in to startProcess");
3559         startProcessLocked(
3560                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3561         checkTime(startTime, "startProcess: done starting proc!");
3562         return (app.pid != 0) ? app : null;
3563     }
3564
3565     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3566         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3567     }
3568
3569     private final void startProcessLocked(ProcessRecord app,
3570             String hostingType, String hostingNameStr) {
3571         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3572                 null /* entryPoint */, null /* entryPointArgs */);
3573     }
3574
3575     private final void startProcessLocked(ProcessRecord app, String hostingType,
3576             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3577         long startTime = SystemClock.elapsedRealtime();
3578         if (app.pid > 0 && app.pid != MY_PID) {
3579             checkTime(startTime, "startProcess: removing from pids map");
3580             synchronized (mPidsSelfLocked) {
3581                 mPidsSelfLocked.remove(app.pid);
3582                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3583             }
3584             checkTime(startTime, "startProcess: done removing from pids map");
3585             app.setPid(0);
3586         }
3587
3588         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3589                 "startProcessLocked removing on hold: " + app);
3590         mProcessesOnHold.remove(app);
3591
3592         checkTime(startTime, "startProcess: starting to update cpu stats");
3593         updateCpuStats();
3594         checkTime(startTime, "startProcess: done updating cpu stats");
3595
3596         try {
3597             try {
3598                 final int userId = UserHandle.getUserId(app.uid);
3599                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3600             } catch (RemoteException e) {
3601                 throw e.rethrowAsRuntimeException();
3602             }
3603
3604             int uid = app.uid;
3605             int[] gids = null;
3606             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3607             if (!app.isolated) {
3608                 int[] permGids = null;
3609                 try {
3610                     checkTime(startTime, "startProcess: getting gids from package manager");
3611                     final IPackageManager pm = AppGlobals.getPackageManager();
3612                     permGids = pm.getPackageGids(app.info.packageName,
3613                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3614                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3615                             MountServiceInternal.class);
3616                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3617                             app.info.packageName);
3618                 } catch (RemoteException e) {
3619                     throw e.rethrowAsRuntimeException();
3620                 }
3621
3622                 /*
3623                  * Add shared application and profile GIDs so applications can share some
3624                  * resources like shared libraries and access user-wide resources
3625                  */
3626                 if (ArrayUtils.isEmpty(permGids)) {
3627                     gids = new int[2];
3628                 } else {
3629                     gids = new int[permGids.length + 2];
3630                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3631                 }
3632                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3633                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3634             }
3635             checkTime(startTime, "startProcess: building args");
3636             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3637                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3638                         && mTopComponent != null
3639                         && app.processName.equals(mTopComponent.getPackageName())) {
3640                     uid = 0;
3641                 }
3642                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3643                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3644                     uid = 0;
3645                 }
3646             }
3647             int debugFlags = 0;
3648             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3649                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3650                 // Also turn on CheckJNI for debuggable apps. It's quite
3651                 // awkward to turn on otherwise.
3652                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3653             }
3654             // Run the app in safe mode if its manifest requests so or the
3655             // system is booted in safe mode.
3656             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3657                 mSafeMode == true) {
3658                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3659             }
3660             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3661                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3662             }
3663             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3664             if ("true".equals(genDebugInfoProperty)) {
3665                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3666             }
3667             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3668                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3669             }
3670             if ("1".equals(SystemProperties.get("debug.assert"))) {
3671                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3672             }
3673             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3674                 // Enable all debug flags required by the native debugger.
3675                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3676                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3677                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3678                 mNativeDebuggingApp = null;
3679             }
3680
3681             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3682             if (requiredAbi == null) {
3683                 requiredAbi = Build.SUPPORTED_ABIS[0];
3684             }
3685
3686             String instructionSet = null;
3687             if (app.info.primaryCpuAbi != null) {
3688                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3689             }
3690
3691             app.gids = gids;
3692             app.requiredAbi = requiredAbi;
3693             app.instructionSet = instructionSet;
3694
3695             // Start the process.  It will either succeed and return a result containing
3696             // the PID of the new process, or else throw a RuntimeException.
3697             boolean isActivityProcess = (entryPoint == null);
3698             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3699             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3700                     app.processName);
3701             checkTime(startTime, "startProcess: asking zygote to start proc");
3702             Process.ProcessStartResult startResult = Process.start(entryPoint,
3703                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3704                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3705                     app.info.dataDir, entryPointArgs);
3706             checkTime(startTime, "startProcess: returned from zygote!");
3707             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3708
3709             if (app.isolated) {
3710                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3711             }
3712             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3713             checkTime(startTime, "startProcess: done updating battery stats");
3714
3715             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3716                     UserHandle.getUserId(uid), startResult.pid, uid,
3717                     app.processName, hostingType,
3718                     hostingNameStr != null ? hostingNameStr : "");
3719
3720             try {
3721                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3722                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3723             } catch (RemoteException ex) {
3724                 // Ignore
3725             }
3726
3727             if (app.persistent) {
3728                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3729             }
3730
3731             checkTime(startTime, "startProcess: building log message");
3732             StringBuilder buf = mStringBuilder;
3733             buf.setLength(0);
3734             buf.append("Start proc ");
3735             buf.append(startResult.pid);
3736             buf.append(':');
3737             buf.append(app.processName);
3738             buf.append('/');
3739             UserHandle.formatUid(buf, uid);
3740             if (!isActivityProcess) {
3741                 buf.append(" [");
3742                 buf.append(entryPoint);
3743                 buf.append("]");
3744             }
3745             buf.append(" for ");
3746             buf.append(hostingType);
3747             if (hostingNameStr != null) {
3748                 buf.append(" ");
3749                 buf.append(hostingNameStr);
3750             }
3751             Slog.i(TAG, buf.toString());
3752             app.setPid(startResult.pid);
3753             app.usingWrapper = startResult.usingWrapper;
3754             app.removed = false;
3755             app.killed = false;
3756             app.killedByAm = false;
3757             checkTime(startTime, "startProcess: starting to update pids map");
3758             synchronized (mPidsSelfLocked) {
3759                 this.mPidsSelfLocked.put(startResult.pid, app);
3760                 if (isActivityProcess) {
3761                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3762                     msg.obj = app;
3763                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3764                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3765                 }
3766             }
3767             checkTime(startTime, "startProcess: done updating pids map");
3768         } catch (RuntimeException e) {
3769             Slog.e(TAG, "Failure starting process " + app.processName, e);
3770
3771             // Something went very wrong while trying to start this process; one
3772             // common case is when the package is frozen due to an active
3773             // upgrade. To recover, clean up any active bookkeeping related to
3774             // starting this process. (We already invoked this method once when
3775             // the package was initially frozen through KILL_APPLICATION_MSG, so
3776             // it doesn't hurt to use it again.)
3777             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3778                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3779         }
3780     }
3781
3782     void updateUsageStats(ActivityRecord component, boolean resumed) {
3783         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3784                 "updateUsageStats: comp=" + component + "res=" + resumed);
3785         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3786         if (resumed) {
3787             if (mUsageStatsService != null) {
3788                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3789                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3790             }
3791             synchronized (stats) {
3792                 stats.noteActivityResumedLocked(component.app.uid);
3793             }
3794         } else {
3795             if (mUsageStatsService != null) {
3796                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3798             }
3799             synchronized (stats) {
3800                 stats.noteActivityPausedLocked(component.app.uid);
3801             }
3802         }
3803     }
3804
3805     Intent getHomeIntent() {
3806         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3807         intent.setComponent(mTopComponent);
3808         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3809         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3810             intent.addCategory(Intent.CATEGORY_HOME);
3811         }
3812         return intent;
3813     }
3814
3815     boolean startHomeActivityLocked(int userId, String reason) {
3816         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3817                 && mTopAction == null) {
3818             // We are running in factory test mode, but unable to find
3819             // the factory test app, so just sit around displaying the
3820             // error message and don't try to start anything.
3821             return false;
3822         }
3823         Intent intent = getHomeIntent();
3824         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3825         if (aInfo != null) {
3826             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3827             // Don't do this if the home app is currently being
3828             // instrumented.
3829             aInfo = new ActivityInfo(aInfo);
3830             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3831             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3832                     aInfo.applicationInfo.uid, true);
3833             if (app == null || app.instrumentationClass == null) {
3834                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3835                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3836             }
3837         } else {
3838             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3839         }
3840
3841         return true;
3842     }
3843
3844     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3845         ActivityInfo ai = null;
3846         ComponentName comp = intent.getComponent();
3847         try {
3848             if (comp != null) {
3849                 // Factory test.
3850                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3851             } else {
3852                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3853                         intent,
3854                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3855                         flags, userId);
3856
3857                 if (info != null) {
3858                     ai = info.activityInfo;
3859                 }
3860             }
3861         } catch (RemoteException e) {
3862             // ignore
3863         }
3864
3865         return ai;
3866     }
3867
3868     /**
3869      * Starts the "new version setup screen" if appropriate.
3870      */
3871     void startSetupActivityLocked() {
3872         // Only do this once per boot.
3873         if (mCheckedForSetup) {
3874             return;
3875         }
3876
3877         // We will show this screen if the current one is a different
3878         // version than the last one shown, and we are not running in
3879         // low-level factory test mode.
3880         final ContentResolver resolver = mContext.getContentResolver();
3881         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3882                 Settings.Global.getInt(resolver,
3883                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3884             mCheckedForSetup = true;
3885
3886             // See if we should be showing the platform update setup UI.
3887             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3888             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3889                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3890             if (!ris.isEmpty()) {
3891                 final ResolveInfo ri = ris.get(0);
3892                 String vers = ri.activityInfo.metaData != null
3893                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3894                         : null;
3895                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3896                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3897                             Intent.METADATA_SETUP_VERSION);
3898                 }
3899                 String lastVers = Settings.Secure.getString(
3900                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3901                 if (vers != null && !vers.equals(lastVers)) {
3902                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3903                     intent.setComponent(new ComponentName(
3904                             ri.activityInfo.packageName, ri.activityInfo.name));
3905                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3906                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3907                             null, 0, 0, 0, null, false, false, null, null, null);
3908                 }
3909             }
3910         }
3911     }
3912
3913     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3914         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3915     }
3916
3917     void enforceNotIsolatedCaller(String caller) {
3918         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3919             throw new SecurityException("Isolated process not allowed to call " + caller);
3920         }
3921     }
3922
3923     void enforceShellRestriction(String restriction, int userHandle) {
3924         if (Binder.getCallingUid() == Process.SHELL_UID) {
3925             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3926                 throw new SecurityException("Shell does not have permission to access user "
3927                         + userHandle);
3928             }
3929         }
3930     }
3931
3932     @Override
3933     public int getFrontActivityScreenCompatMode() {
3934         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3935         synchronized (this) {
3936             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3937         }
3938     }
3939
3940     @Override
3941     public void setFrontActivityScreenCompatMode(int mode) {
3942         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3943                 "setFrontActivityScreenCompatMode");
3944         synchronized (this) {
3945             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3946         }
3947     }
3948
3949     @Override
3950     public int getPackageScreenCompatMode(String packageName) {
3951         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3952         synchronized (this) {
3953             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3954         }
3955     }
3956
3957     @Override
3958     public void setPackageScreenCompatMode(String packageName, int mode) {
3959         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3960                 "setPackageScreenCompatMode");
3961         synchronized (this) {
3962             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3963         }
3964     }
3965
3966     @Override
3967     public boolean getPackageAskScreenCompat(String packageName) {
3968         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3969         synchronized (this) {
3970             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3971         }
3972     }
3973
3974     @Override
3975     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3976         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977                 "setPackageAskScreenCompat");
3978         synchronized (this) {
3979             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3980         }
3981     }
3982
3983     private boolean hasUsageStatsPermission(String callingPackage) {
3984         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3985                 Binder.getCallingUid(), callingPackage);
3986         if (mode == AppOpsManager.MODE_DEFAULT) {
3987             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3988                     == PackageManager.PERMISSION_GRANTED;
3989         }
3990         return mode == AppOpsManager.MODE_ALLOWED;
3991     }
3992
3993     @Override
3994     public int getPackageProcessState(String packageName, String callingPackage) {
3995         if (!hasUsageStatsPermission(callingPackage)) {
3996             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3997                     "getPackageProcessState");
3998         }
3999
4000         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4001         synchronized (this) {
4002             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003                 final ProcessRecord proc = mLruProcesses.get(i);
4004                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4005                         || procState > proc.setProcState) {
4006                     boolean found = false;
4007                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4008                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4009                             procState = proc.setProcState;
4010                             found = true;
4011                         }
4012                     }
4013                     if (proc.pkgDeps != null && !found) {
4014                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4015                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4016                                 procState = proc.setProcState;
4017                                 break;
4018                             }
4019                         }
4020                     }
4021                 }
4022             }
4023         }
4024         return procState;
4025     }
4026
4027     @Override
4028     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4029         synchronized (this) {
4030             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4031             if (app == null) {
4032                 return false;
4033             }
4034             if (app.trimMemoryLevel < level && app.thread != null &&
4035                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4036                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4037                 try {
4038                     app.thread.scheduleTrimMemory(level);
4039                     app.trimMemoryLevel = level;
4040                     return true;
4041                 } catch (RemoteException e) {
4042                     // Fallthrough to failure case.
4043                 }
4044             }
4045         }
4046         return false;
4047     }
4048
4049     private void dispatchProcessesChanged() {
4050         int N;
4051         synchronized (this) {
4052             N = mPendingProcessChanges.size();
4053             if (mActiveProcessChanges.length < N) {
4054                 mActiveProcessChanges = new ProcessChangeItem[N];
4055             }
4056             mPendingProcessChanges.toArray(mActiveProcessChanges);
4057             mPendingProcessChanges.clear();
4058             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059                     "*** Delivering " + N + " process changes");
4060         }
4061
4062         int i = mProcessObservers.beginBroadcast();
4063         while (i > 0) {
4064             i--;
4065             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066             if (observer != null) {
4067                 try {
4068                     for (int j=0; j<N; j++) {
4069                         ProcessChangeItem item = mActiveProcessChanges[j];
4070                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073                                     + item.uid + ": " + item.foregroundActivities);
4074                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075                                     item.foregroundActivities);
4076                         }
4077                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080                                     + ": " + item.processState);
4081                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4082                         }
4083                     }
4084                 } catch (RemoteException e) {
4085                 }
4086             }
4087         }
4088         mProcessObservers.finishBroadcast();
4089
4090         synchronized (this) {
4091             for (int j=0; j<N; j++) {
4092                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4093             }
4094         }
4095     }
4096
4097     private void dispatchProcessDied(int pid, int uid) {
4098         int i = mProcessObservers.beginBroadcast();
4099         while (i > 0) {
4100             i--;
4101             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102             if (observer != null) {
4103                 try {
4104                     observer.onProcessDied(pid, uid);
4105                 } catch (RemoteException e) {
4106                 }
4107             }
4108         }
4109         mProcessObservers.finishBroadcast();
4110     }
4111
4112     private void dispatchUidsChanged() {
4113         int N;
4114         synchronized (this) {
4115             N = mPendingUidChanges.size();
4116             if (mActiveUidChanges.length < N) {
4117                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4118             }
4119             for (int i=0; i<N; i++) {
4120                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121                 mActiveUidChanges[i] = change;
4122                 if (change.uidRecord != null) {
4123                     change.uidRecord.pendingChange = null;
4124                     change.uidRecord = null;
4125                 }
4126             }
4127             mPendingUidChanges.clear();
4128             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                     "*** Delivering " + N + " uid changes");
4130         }
4131
4132         if (mLocalPowerManager != null) {
4133             for (int j=0; j<N; j++) {
4134                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4135                 if (item.change == UidRecord.CHANGE_GONE
4136                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4137                     mLocalPowerManager.uidGone(item.uid);
4138                 } else {
4139                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4140                 }
4141             }
4142         }
4143
4144         int i = mUidObservers.beginBroadcast();
4145         while (i > 0) {
4146             i--;
4147             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4148             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4149             if (observer != null) {
4150                 try {
4151                     for (int j=0; j<N; j++) {
4152                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4153                         final int change = item.change;
4154                         UidRecord validateUid = null;
4155                         if (VALIDATE_UID_STATES && i == 0) {
4156                             validateUid = mValidateUids.get(item.uid);
4157                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4158                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4159                                 validateUid = new UidRecord(item.uid);
4160                                 mValidateUids.put(item.uid, validateUid);
4161                             }
4162                         }
4163                         if (change == UidRecord.CHANGE_IDLE
4164                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4165                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4166                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                                         "UID idle uid=" + item.uid);
4168                                 observer.onUidIdle(item.uid);
4169                             }
4170                             if (VALIDATE_UID_STATES && i == 0) {
4171                                 if (validateUid != null) {
4172                                     validateUid.idle = true;
4173                                 }
4174                             }
4175                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4176                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4177                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178                                         "UID active uid=" + item.uid);
4179                                 observer.onUidActive(item.uid);
4180                             }
4181                             if (VALIDATE_UID_STATES && i == 0) {
4182                                 validateUid.idle = false;
4183                             }
4184                         }
4185                         if (change == UidRecord.CHANGE_GONE
4186                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4187                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4188                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4189                                         "UID gone uid=" + item.uid);
4190                                 observer.onUidGone(item.uid);
4191                             }
4192                             if (VALIDATE_UID_STATES && i == 0) {
4193                                 if (validateUid != null) {
4194                                     mValidateUids.remove(item.uid);
4195                                 }
4196                             }
4197                         } else {
4198                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4199                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                                         "UID CHANGED uid=" + item.uid
4201                                                 + ": " + item.processState);
4202                                 observer.onUidStateChanged(item.uid, item.processState);
4203                             }
4204                             if (VALIDATE_UID_STATES && i == 0) {
4205                                 validateUid.curProcState = validateUid.setProcState
4206                                         = item.processState;
4207                             }
4208                         }
4209                     }
4210                 } catch (RemoteException e) {
4211                 }
4212             }
4213         }
4214         mUidObservers.finishBroadcast();
4215
4216         synchronized (this) {
4217             for (int j=0; j<N; j++) {
4218                 mAvailUidChanges.add(mActiveUidChanges[j]);
4219             }
4220         }
4221     }
4222
4223     @Override
4224     public final int startActivity(IApplicationThread caller, String callingPackage,
4225             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4226             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4227         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4228                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4229                 UserHandle.getCallingUserId());
4230     }
4231
4232     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4233         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4234         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4235                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4236                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4237
4238         // TODO: Switch to user app stacks here.
4239         String mimeType = intent.getType();
4240         final Uri data = intent.getData();
4241         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4242             mimeType = getProviderMimeType(data, userId);
4243         }
4244         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4245
4246         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4247         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4248                 null, 0, 0, null, null, null, null, false, userId, container, null);
4249     }
4250
4251     @Override
4252     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4253             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4254             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4255         enforceNotIsolatedCaller("startActivity");
4256         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4257                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4258         // TODO: Switch to user app stacks here.
4259         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4260                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4261                 profilerInfo, null, null, bOptions, false, userId, null, null);
4262     }
4263
4264     @Override
4265     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4266             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4268             int userId) {
4269
4270         // This is very dangerous -- it allows you to perform a start activity (including
4271         // permission grants) as any app that may launch one of your own activities.  So
4272         // we will only allow this to be done from activities that are part of the core framework,
4273         // and then only when they are running as the system.
4274         final ActivityRecord sourceRecord;
4275         final int targetUid;
4276         final String targetPackage;
4277         synchronized (this) {
4278             if (resultTo == null) {
4279                 throw new SecurityException("Must be called from an activity");
4280             }
4281             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4282             if (sourceRecord == null) {
4283                 throw new SecurityException("Called with bad activity token: " + resultTo);
4284             }
4285             if (!sourceRecord.info.packageName.equals("android")) {
4286                 throw new SecurityException(
4287                         "Must be called from an activity that is declared in the android package");
4288             }
4289             if (sourceRecord.app == null) {
4290                 throw new SecurityException("Called without a process attached to activity");
4291             }
4292             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4293                 // This is still okay, as long as this activity is running under the
4294                 // uid of the original calling activity.
4295                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4296                     throw new SecurityException(
4297                             "Calling activity in uid " + sourceRecord.app.uid
4298                                     + " must be system uid or original calling uid "
4299                                     + sourceRecord.launchedFromUid);
4300                 }
4301             }
4302             if (ignoreTargetSecurity) {
4303                 if (intent.getComponent() == null) {
4304                     throw new SecurityException(
4305                             "Component must be specified with ignoreTargetSecurity");
4306                 }
4307                 if (intent.getSelector() != null) {
4308                     throw new SecurityException(
4309                             "Selector not allowed with ignoreTargetSecurity");
4310                 }
4311             }
4312             targetUid = sourceRecord.launchedFromUid;
4313             targetPackage = sourceRecord.launchedFromPackage;
4314         }
4315
4316         if (userId == UserHandle.USER_NULL) {
4317             userId = UserHandle.getUserId(sourceRecord.app.uid);
4318         }
4319
4320         // TODO: Switch to user app stacks here.
4321         try {
4322             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4323                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4324                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4325             return ret;
4326         } catch (SecurityException e) {
4327             // XXX need to figure out how to propagate to original app.
4328             // A SecurityException here is generally actually a fault of the original
4329             // calling activity (such as a fairly granting permissions), so propagate it
4330             // back to them.
4331             /*
4332             StringBuilder msg = new StringBuilder();
4333             msg.append("While launching");
4334             msg.append(intent.toString());
4335             msg.append(": ");
4336             msg.append(e.getMessage());
4337             */
4338             throw e;
4339         }
4340     }
4341
4342     @Override
4343     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4344             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4345             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4346         enforceNotIsolatedCaller("startActivityAndWait");
4347         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4349         WaitResult res = new WaitResult();
4350         // TODO: Switch to user app stacks here.
4351         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4352                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4353                 bOptions, false, userId, null, null);
4354         return res;
4355     }
4356
4357     @Override
4358     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4359             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360             int startFlags, Configuration config, Bundle bOptions, int userId) {
4361         enforceNotIsolatedCaller("startActivityWithConfig");
4362         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4364         // TODO: Switch to user app stacks here.
4365         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4366                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4367                 null, null, config, bOptions, false, userId, null, null);
4368         return ret;
4369     }
4370
4371     @Override
4372     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4373             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4374             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4375             throws TransactionTooLargeException {
4376         enforceNotIsolatedCaller("startActivityIntentSender");
4377         // Refuse possible leaked file descriptors
4378         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4379             throw new IllegalArgumentException("File descriptors passed in Intent");
4380         }
4381
4382         IIntentSender sender = intent.getTarget();
4383         if (!(sender instanceof PendingIntentRecord)) {
4384             throw new IllegalArgumentException("Bad PendingIntent object");
4385         }
4386
4387         PendingIntentRecord pir = (PendingIntentRecord)sender;
4388
4389         synchronized (this) {
4390             // If this is coming from the currently resumed activity, it is
4391             // effectively saying that app switches are allowed at this point.
4392             final ActivityStack stack = getFocusedStack();
4393             if (stack.mResumedActivity != null &&
4394                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4395                 mAppSwitchesAllowedTime = 0;
4396             }
4397         }
4398         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4399                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4400         return ret;
4401     }
4402
4403     @Override
4404     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4405             Intent intent, String resolvedType, IVoiceInteractionSession session,
4406             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4407             Bundle bOptions, int userId) {
4408         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4409                 != PackageManager.PERMISSION_GRANTED) {
4410             String msg = "Permission Denial: startVoiceActivity() from pid="
4411                     + Binder.getCallingPid()
4412                     + ", uid=" + Binder.getCallingUid()
4413                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4414             Slog.w(TAG, msg);
4415             throw new SecurityException(msg);
4416         }
4417         if (session == null || interactor == null) {
4418             throw new NullPointerException("null session or interactor");
4419         }
4420         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4421                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4422         // TODO: Switch to user app stacks here.
4423         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4424                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4425                 null, bOptions, false, userId, null, null);
4426     }
4427
4428     @Override
4429     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4430             throws RemoteException {
4431         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4432         synchronized (this) {
4433             ActivityRecord activity = getFocusedStack().topActivity();
4434             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4435                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4436             }
4437             if (mRunningVoice != null || activity.task.voiceSession != null
4438                     || activity.voiceSession != null) {
4439                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4440                 return;
4441             }
4442             if (activity.pendingVoiceInteractionStart) {
4443                 Slog.w(TAG, "Pending start of voice interaction already.");
4444                 return;
4445             }
4446             activity.pendingVoiceInteractionStart = true;
4447         }
4448         LocalServices.getService(VoiceInteractionManagerInternal.class)
4449                 .startLocalVoiceInteraction(callingActivity, options);
4450     }
4451
4452     @Override
4453     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4454         LocalServices.getService(VoiceInteractionManagerInternal.class)
4455                 .stopLocalVoiceInteraction(callingActivity);
4456     }
4457
4458     @Override
4459     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4460         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4461                 .supportsLocalVoiceInteraction();
4462     }
4463
4464     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4465             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4466         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4467         if (activityToCallback == null) return;
4468         activityToCallback.setVoiceSessionLocked(voiceSession);
4469
4470         // Inform the activity
4471         try {
4472             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4473                     voiceInteractor);
4474             long token = Binder.clearCallingIdentity();
4475             try {
4476                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4477             } finally {
4478                 Binder.restoreCallingIdentity(token);
4479             }
4480             // TODO: VI Should we cache the activity so that it's easier to find later
4481             // rather than scan through all the stacks and activities?
4482         } catch (RemoteException re) {
4483             activityToCallback.clearVoiceSessionLocked();
4484             // TODO: VI Should this terminate the voice session?
4485         }
4486     }
4487
4488     @Override
4489     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4490         synchronized (this) {
4491             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4492                 if (keepAwake) {
4493                     mVoiceWakeLock.acquire();
4494                 } else {
4495                     mVoiceWakeLock.release();
4496                 }
4497             }
4498         }
4499     }
4500
4501     @Override
4502     public boolean startNextMatchingActivity(IBinder callingActivity,
4503             Intent intent, Bundle bOptions) {
4504         // Refuse possible leaked file descriptors
4505         if (intent != null && intent.hasFileDescriptors() == true) {
4506             throw new IllegalArgumentException("File descriptors passed in Intent");
4507         }
4508         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4509
4510         synchronized (this) {
4511             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4512             if (r == null) {
4513                 ActivityOptions.abort(options);
4514                 return false;
4515             }
4516             if (r.app == null || r.app.thread == null) {
4517                 // The caller is not running...  d'oh!
4518                 ActivityOptions.abort(options);
4519                 return false;
4520             }
4521             intent = new Intent(intent);
4522             // The caller is not allowed to change the data.
4523             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4524             // And we are resetting to find the next component...
4525             intent.setComponent(null);
4526
4527             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4528
4529             ActivityInfo aInfo = null;
4530             try {
4531                 List<ResolveInfo> resolves =
4532                     AppGlobals.getPackageManager().queryIntentActivities(
4533                             intent, r.resolvedType,
4534                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4535                             UserHandle.getCallingUserId()).getList();
4536
4537                 // Look for the original activity in the list...
4538                 final int N = resolves != null ? resolves.size() : 0;
4539                 for (int i=0; i<N; i++) {
4540                     ResolveInfo rInfo = resolves.get(i);
4541                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4542                             && rInfo.activityInfo.name.equals(r.info.name)) {
4543                         // We found the current one...  the next matching is
4544                         // after it.
4545                         i++;
4546                         if (i<N) {
4547                             aInfo = resolves.get(i).activityInfo;
4548                         }
4549                         if (debug) {
4550                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4551                                     + "/" + r.info.name);
4552                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4553                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4554                         }
4555                         break;
4556                     }
4557                 }
4558             } catch (RemoteException e) {
4559             }
4560
4561             if (aInfo == null) {
4562                 // Nobody who is next!
4563                 ActivityOptions.abort(options);
4564                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4565                 return false;
4566             }
4567
4568             intent.setComponent(new ComponentName(
4569                     aInfo.applicationInfo.packageName, aInfo.name));
4570             intent.setFlags(intent.getFlags()&~(
4571                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4572                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4573                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4574                     Intent.FLAG_ACTIVITY_NEW_TASK));
4575
4576             // Okay now we need to start the new activity, replacing the
4577             // currently running activity.  This is a little tricky because
4578             // we want to start the new one as if the current one is finished,
4579             // but not finish the current one first so that there is no flicker.
4580             // And thus...
4581             final boolean wasFinishing = r.finishing;
4582             r.finishing = true;
4583
4584             // Propagate reply information over to the new activity.
4585             final ActivityRecord resultTo = r.resultTo;
4586             final String resultWho = r.resultWho;
4587             final int requestCode = r.requestCode;
4588             r.resultTo = null;
4589             if (resultTo != null) {
4590                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4591             }
4592
4593             final long origId = Binder.clearCallingIdentity();
4594             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4595                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4596                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4597                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4598                     false, false, null, null, null);
4599             Binder.restoreCallingIdentity(origId);
4600
4601             r.finishing = wasFinishing;
4602             if (res != ActivityManager.START_SUCCESS) {
4603                 return false;
4604             }
4605             return true;
4606         }
4607     }
4608
4609     @Override
4610     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4611         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4612             String msg = "Permission Denial: startActivityFromRecents called without " +
4613                     START_TASKS_FROM_RECENTS;
4614             Slog.w(TAG, msg);
4615             throw new SecurityException(msg);
4616         }
4617         final long origId = Binder.clearCallingIdentity();
4618         try {
4619             synchronized (this) {
4620                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4621             }
4622         } finally {
4623             Binder.restoreCallingIdentity(origId);
4624         }
4625     }
4626
4627     final int startActivityInPackage(int uid, String callingPackage,
4628             Intent intent, String resolvedType, IBinder resultTo,
4629             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4630             IActivityContainer container, TaskRecord inTask) {
4631
4632         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4633                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4634
4635         // TODO: Switch to user app stacks here.
4636         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4637                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4638                 null, null, null, bOptions, false, userId, container, inTask);
4639         return ret;
4640     }
4641
4642     @Override
4643     public final int startActivities(IApplicationThread caller, String callingPackage,
4644             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4645             int userId) {
4646         enforceNotIsolatedCaller("startActivities");
4647         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4648                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4649         // TODO: Switch to user app stacks here.
4650         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4651                 resolvedTypes, resultTo, bOptions, userId);
4652         return ret;
4653     }
4654
4655     final int startActivitiesInPackage(int uid, String callingPackage,
4656             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4657             Bundle bOptions, int userId) {
4658
4659         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4660                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4661         // TODO: Switch to user app stacks here.
4662         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4663                 resultTo, bOptions, userId);
4664         return ret;
4665     }
4666
4667     @Override
4668     public void reportActivityFullyDrawn(IBinder token) {
4669         synchronized (this) {
4670             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671             if (r == null) {
4672                 return;
4673             }
4674             r.reportFullyDrawnLocked();
4675         }
4676     }
4677
4678     @Override
4679     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4680         synchronized (this) {
4681             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682             if (r == null) {
4683                 return;
4684             }
4685             TaskRecord task = r.task;
4686             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4687                 // Fixed screen orientation isn't supported when activities aren't in full screen
4688                 // mode.
4689                 return;
4690             }
4691             final long origId = Binder.clearCallingIdentity();
4692             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4693             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4694                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4695             if (config != null) {
4696                 r.frozenBeforeDestroy = true;
4697                 if (!updateConfigurationLocked(config, r, false)) {
4698                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4699                 }
4700             }
4701             Binder.restoreCallingIdentity(origId);
4702         }
4703     }
4704
4705     @Override
4706     public int getRequestedOrientation(IBinder token) {
4707         synchronized (this) {
4708             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4709             if (r == null) {
4710                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4711             }
4712             return mWindowManager.getAppOrientation(r.appToken);
4713         }
4714     }
4715
4716     /**
4717      * This is the internal entry point for handling Activity.finish().
4718      *
4719      * @param token The Binder token referencing the Activity we want to finish.
4720      * @param resultCode Result code, if any, from this Activity.
4721      * @param resultData Result data (Intent), if any, from this Activity.
4722      * @param finishTask Whether to finish the task associated with this Activity.
4723      *
4724      * @return Returns true if the activity successfully finished, or false if it is still running.
4725      */
4726     @Override
4727     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4728             int finishTask) {
4729         // Refuse possible leaked file descriptors
4730         if (resultData != null && resultData.hasFileDescriptors() == true) {
4731             throw new IllegalArgumentException("File descriptors passed in Intent");
4732         }
4733
4734         synchronized(this) {
4735             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736             if (r == null) {
4737                 return true;
4738             }
4739             // Keep track of the root activity of the task before we finish it
4740             TaskRecord tr = r.task;
4741             ActivityRecord rootR = tr.getRootActivity();
4742             if (rootR == null) {
4743                 Slog.w(TAG, "Finishing task with all activities already finished");
4744             }
4745             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4746             // finish.
4747             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4748                     mStackSupervisor.isLastLockedTask(tr)) {
4749                 Slog.i(TAG, "Not finishing task in lock task mode");
4750                 mStackSupervisor.showLockTaskToast();
4751                 return false;
4752             }
4753             if (mController != null) {
4754                 // Find the first activity that is not finishing.
4755                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4756                 if (next != null) {
4757                     // ask watcher if this is allowed
4758                     boolean resumeOK = true;
4759                     try {
4760                         resumeOK = mController.activityResuming(next.packageName);
4761                     } catch (RemoteException e) {
4762                         mController = null;
4763                         Watchdog.getInstance().setActivityController(null);
4764                     }
4765
4766                     if (!resumeOK) {
4767                         Slog.i(TAG, "Not finishing activity because controller resumed");
4768                         return false;
4769                     }
4770                 }
4771             }
4772             final long origId = Binder.clearCallingIdentity();
4773             try {
4774                 boolean res;
4775                 final boolean finishWithRootActivity =
4776                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4777                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4778                         || (finishWithRootActivity && r == rootR)) {
4779                     // If requested, remove the task that is associated to this activity only if it
4780                     // was the root activity in the task. The result code and data is ignored
4781                     // because we don't support returning them across task boundaries. Also, to
4782                     // keep backwards compatibility we remove the task from recents when finishing
4783                     // task with root activity.
4784                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4785                     if (!res) {
4786                         Slog.i(TAG, "Removing task failed to finish activity");
4787                     }
4788                 } else {
4789                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4790                             resultData, "app-request", true);
4791                     if (!res) {
4792                         Slog.i(TAG, "Failed to finish by app-request");
4793                     }
4794                 }
4795                 return res;
4796             } finally {
4797                 Binder.restoreCallingIdentity(origId);
4798             }
4799         }
4800     }
4801
4802     @Override
4803     public final void finishHeavyWeightApp() {
4804         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805                 != PackageManager.PERMISSION_GRANTED) {
4806             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4807                     + Binder.getCallingPid()
4808                     + ", uid=" + Binder.getCallingUid()
4809                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4810             Slog.w(TAG, msg);
4811             throw new SecurityException(msg);
4812         }
4813
4814         synchronized(this) {
4815             if (mHeavyWeightProcess == null) {
4816                 return;
4817             }
4818
4819             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4820             for (int i = 0; i < activities.size(); i++) {
4821                 ActivityRecord r = activities.get(i);
4822                 if (!r.finishing && r.isInStackLocked()) {
4823                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4824                             null, "finish-heavy", true);
4825                 }
4826             }
4827
4828             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4829                     mHeavyWeightProcess.userId, 0));
4830             mHeavyWeightProcess = null;
4831         }
4832     }
4833
4834     @Override
4835     public void crashApplication(int uid, int initialPid, String packageName,
4836             String message) {
4837         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4838                 != PackageManager.PERMISSION_GRANTED) {
4839             String msg = "Permission Denial: crashApplication() from pid="
4840                     + Binder.getCallingPid()
4841                     + ", uid=" + Binder.getCallingUid()
4842                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4843             Slog.w(TAG, msg);
4844             throw new SecurityException(msg);
4845         }
4846
4847         synchronized(this) {
4848             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4849         }
4850     }
4851
4852     @Override
4853     public final void finishSubActivity(IBinder token, String resultWho,
4854             int requestCode) {
4855         synchronized(this) {
4856             final long origId = Binder.clearCallingIdentity();
4857             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4858             if (r != null) {
4859                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4860             }
4861             Binder.restoreCallingIdentity(origId);
4862         }
4863     }
4864
4865     @Override
4866     public boolean finishActivityAffinity(IBinder token) {
4867         synchronized(this) {
4868             final long origId = Binder.clearCallingIdentity();
4869             try {
4870                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4871                 if (r == null) {
4872                     return false;
4873                 }
4874
4875                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4876                 // can finish.
4877                 final TaskRecord task = r.task;
4878                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4879                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4880                     mStackSupervisor.showLockTaskToast();
4881                     return false;
4882                 }
4883                 return task.stack.finishActivityAffinityLocked(r);
4884             } finally {
4885                 Binder.restoreCallingIdentity(origId);
4886             }
4887         }
4888     }
4889
4890     @Override
4891     public void finishVoiceTask(IVoiceInteractionSession session) {
4892         synchronized (this) {
4893             final long origId = Binder.clearCallingIdentity();
4894             try {
4895                 // TODO: VI Consider treating local voice interactions and voice tasks
4896                 // differently here
4897                 mStackSupervisor.finishVoiceTask(session);
4898             } finally {
4899                 Binder.restoreCallingIdentity(origId);
4900             }
4901         }
4902
4903     }
4904
4905     @Override
4906     public boolean releaseActivityInstance(IBinder token) {
4907         synchronized(this) {
4908             final long origId = Binder.clearCallingIdentity();
4909             try {
4910                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911                 if (r == null) {
4912                     return false;
4913                 }
4914                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4915             } finally {
4916                 Binder.restoreCallingIdentity(origId);
4917             }
4918         }
4919     }
4920
4921     @Override
4922     public void releaseSomeActivities(IApplicationThread appInt) {
4923         synchronized(this) {
4924             final long origId = Binder.clearCallingIdentity();
4925             try {
4926                 ProcessRecord app = getRecordForAppLocked(appInt);
4927                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4928             } finally {
4929                 Binder.restoreCallingIdentity(origId);
4930             }
4931         }
4932     }
4933
4934     @Override
4935     public boolean willActivityBeVisible(IBinder token) {
4936         synchronized(this) {
4937             ActivityStack stack = ActivityRecord.getStackLocked(token);
4938             if (stack != null) {
4939                 return stack.willActivityBeVisibleLocked(token);
4940             }
4941             return false;
4942         }
4943     }
4944
4945     @Override
4946     public void overridePendingTransition(IBinder token, String packageName,
4947             int enterAnim, int exitAnim) {
4948         synchronized(this) {
4949             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4950             if (self == null) {
4951                 return;
4952             }
4953
4954             final long origId = Binder.clearCallingIdentity();
4955
4956             if (self.state == ActivityState.RESUMED
4957                     || self.state == ActivityState.PAUSING) {
4958                 mWindowManager.overridePendingAppTransition(packageName,
4959                         enterAnim, exitAnim, null);
4960             }
4961
4962             Binder.restoreCallingIdentity(origId);
4963         }
4964     }
4965
4966     /**
4967      * Main function for removing an existing process from the activity manager
4968      * as a result of that process going away.  Clears out all connections
4969      * to the process.
4970      */
4971     private final void handleAppDiedLocked(ProcessRecord app,
4972             boolean restarting, boolean allowRestart) {
4973         int pid = app.pid;
4974         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4975         if (!kept && !restarting) {
4976             removeLruProcessLocked(app);
4977             if (pid > 0) {
4978                 ProcessList.remove(pid);
4979             }
4980         }
4981
4982         if (mProfileProc == app) {
4983             clearProfilerLocked();
4984         }
4985
4986         // Remove this application's activities from active lists.
4987         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4988
4989         app.activities.clear();
4990
4991         if (app.instrumentationClass != null) {
4992             Slog.w(TAG, "Crash of app " + app.processName
4993                   + " running instrumentation " + app.instrumentationClass);
4994             Bundle info = new Bundle();
4995             info.putString("shortMsg", "Process crashed.");
4996             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4997         }
4998
4999         if (!restarting && hasVisibleActivities
5000                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5001             // If there was nothing to resume, and we are not already restarting this process, but
5002             // there is a visible activity that is hosted by the process...  then make sure all
5003             // visible activities are running, taking care of restarting this process.
5004             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5005         }
5006     }
5007
5008     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5009         IBinder threadBinder = thread.asBinder();
5010         // Find the application record.
5011         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012             ProcessRecord rec = mLruProcesses.get(i);
5013             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5014                 return i;
5015             }
5016         }
5017         return -1;
5018     }
5019
5020     final ProcessRecord getRecordForAppLocked(
5021             IApplicationThread thread) {
5022         if (thread == null) {
5023             return null;
5024         }
5025
5026         int appIndex = getLRURecordIndexForAppLocked(thread);
5027         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5028     }
5029
5030     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5031         // If there are no longer any background processes running,
5032         // and the app that died was not running instrumentation,
5033         // then tell everyone we are now low on memory.
5034         boolean haveBg = false;
5035         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036             ProcessRecord rec = mLruProcesses.get(i);
5037             if (rec.thread != null
5038                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5039                 haveBg = true;
5040                 break;
5041             }
5042         }
5043
5044         if (!haveBg) {
5045             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5046             if (doReport) {
5047                 long now = SystemClock.uptimeMillis();
5048                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5049                     doReport = false;
5050                 } else {
5051                     mLastMemUsageReportTime = now;
5052                 }
5053             }
5054             final ArrayList<ProcessMemInfo> memInfos
5055                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5056             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5057             long now = SystemClock.uptimeMillis();
5058             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059                 ProcessRecord rec = mLruProcesses.get(i);
5060                 if (rec == dyingProc || rec.thread == null) {
5061                     continue;
5062                 }
5063                 if (doReport) {
5064                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5065                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5066                 }
5067                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5068                     // The low memory report is overriding any current
5069                     // state for a GC request.  Make sure to do
5070                     // heavy/important/visible/foreground processes first.
5071                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5072                         rec.lastRequestedGc = 0;
5073                     } else {
5074                         rec.lastRequestedGc = rec.lastLowMemory;
5075                     }
5076                     rec.reportLowMemory = true;
5077                     rec.lastLowMemory = now;
5078                     mProcessesToGc.remove(rec);
5079                     addProcessToGcListLocked(rec);
5080                 }
5081             }
5082             if (doReport) {
5083                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5084                 mHandler.sendMessage(msg);
5085             }
5086             scheduleAppGcsLocked();
5087         }
5088     }
5089
5090     final void appDiedLocked(ProcessRecord app) {
5091        appDiedLocked(app, app.pid, app.thread, false);
5092     }
5093
5094     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5095             boolean fromBinderDied) {
5096         // First check if this ProcessRecord is actually active for the pid.
5097         synchronized (mPidsSelfLocked) {
5098             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5099             if (curProc != app) {
5100                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5101                 return;
5102             }
5103         }
5104
5105         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5106         synchronized (stats) {
5107             stats.noteProcessDiedLocked(app.info.uid, pid);
5108         }
5109
5110         if (!app.killed) {
5111             if (!fromBinderDied) {
5112                 Process.killProcessQuiet(pid);
5113             }
5114             killProcessGroup(app.uid, pid);
5115             app.killed = true;
5116         }
5117
5118         // Clean up already done if the process has been re-started.
5119         if (app.pid == pid && app.thread != null &&
5120                 app.thread.asBinder() == thread.asBinder()) {
5121             boolean doLowMem = app.instrumentationClass == null;
5122             boolean doOomAdj = doLowMem;
5123             if (!app.killedByAm) {
5124                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5125                         + ") has died");
5126                 mAllowLowerMemLevel = true;
5127             } else {
5128                 // Note that we always want to do oom adj to update our state with the
5129                 // new number of procs.
5130                 mAllowLowerMemLevel = false;
5131                 doLowMem = false;
5132             }
5133             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5134             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5135                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5136             handleAppDiedLocked(app, false, true);
5137
5138             if (doOomAdj) {
5139                 updateOomAdjLocked();
5140             }
5141             if (doLowMem) {
5142                 doLowMemReportIfNeededLocked(app);
5143             }
5144         } else if (app.pid != pid) {
5145             // A new process has already been started.
5146             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5147                     + ") has died and restarted (pid " + app.pid + ").");
5148             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5149         } else if (DEBUG_PROCESSES) {
5150             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5151                     + thread.asBinder());
5152         }
5153     }
5154
5155     /**
5156      * If a stack trace dump file is configured, dump process stack traces.
5157      * @param clearTraces causes the dump file to be erased prior to the new
5158      *    traces being written, if true; when false, the new traces will be
5159      *    appended to any existing file content.
5160      * @param firstPids of dalvik VM processes to dump stack traces for first
5161      * @param lastPids of dalvik VM processes to dump stack traces for last
5162      * @param nativeProcs optional list of native process names to dump stack crawls
5163      * @return file containing stack traces, or null if no dump file is configured
5164      */
5165     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5166             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5167         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5168         if (tracesPath == null || tracesPath.length() == 0) {
5169             return null;
5170         }
5171
5172         File tracesFile = new File(tracesPath);
5173         try {
5174             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5175             tracesFile.createNewFile();
5176             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5177         } catch (IOException e) {
5178             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5179             return null;
5180         }
5181
5182         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5183         return tracesFile;
5184     }
5185
5186     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5187             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5188         // Use a FileObserver to detect when traces finish writing.
5189         // The order of traces is considered important to maintain for legibility.
5190         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5191             @Override
5192             public synchronized void onEvent(int event, String path) { notify(); }
5193         };
5194
5195         try {
5196             observer.startWatching();
5197
5198             // First collect all of the stacks of the most important pids.
5199             if (firstPids != null) {
5200                 try {
5201                     int num = firstPids.size();
5202                     for (int i = 0; i < num; i++) {
5203                         synchronized (observer) {
5204                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5205                                     + firstPids.get(i));
5206                             final long sime = SystemClock.elapsedRealtime();
5207                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5208                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5209                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5210                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5211                         }
5212                     }
5213                 } catch (InterruptedException e) {
5214                     Slog.wtf(TAG, e);
5215                 }
5216             }
5217
5218             // Next collect the stacks of the native pids
5219             if (nativeProcs != null) {
5220                 int[] pids = Process.getPidsForCommands(nativeProcs);
5221                 if (pids != null) {
5222                     for (int pid : pids) {
5223                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5224                         final long sime = SystemClock.elapsedRealtime();
5225                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5226                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5227                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5228                     }
5229                 }
5230             }
5231
5232             // Lastly, measure CPU usage.
5233             if (processCpuTracker != null) {
5234                 processCpuTracker.init();
5235                 System.gc();
5236                 processCpuTracker.update();
5237                 try {
5238                     synchronized (processCpuTracker) {
5239                         processCpuTracker.wait(500); // measure over 1/2 second.
5240                     }
5241                 } catch (InterruptedException e) {
5242                 }
5243                 processCpuTracker.update();
5244
5245                 // We'll take the stack crawls of just the top apps using CPU.
5246                 final int N = processCpuTracker.countWorkingStats();
5247                 int numProcs = 0;
5248                 for (int i=0; i<N && numProcs<5; i++) {
5249                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5250                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5251                         numProcs++;
5252                         try {
5253                             synchronized (observer) {
5254                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5255                                         + stats.pid);
5256                                 final long stime = SystemClock.elapsedRealtime();
5257                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5258                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5259                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5260                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5261                             }
5262                         } catch (InterruptedException e) {
5263                             Slog.wtf(TAG, e);
5264                         }
5265                     } else if (DEBUG_ANR) {
5266                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5267                                 + stats.pid);
5268                     }
5269                 }
5270             }
5271         } finally {
5272             observer.stopWatching();
5273         }
5274     }
5275
5276     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5277         if (true || IS_USER_BUILD) {
5278             return;
5279         }
5280         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5281         if (tracesPath == null || tracesPath.length() == 0) {
5282             return;
5283         }
5284
5285         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5286         StrictMode.allowThreadDiskWrites();
5287         try {
5288             final File tracesFile = new File(tracesPath);
5289             final File tracesDir = tracesFile.getParentFile();
5290             final File tracesTmp = new File(tracesDir, "__tmp__");
5291             try {
5292                 if (tracesFile.exists()) {
5293                     tracesTmp.delete();
5294                     tracesFile.renameTo(tracesTmp);
5295                 }
5296                 StringBuilder sb = new StringBuilder();
5297                 Time tobj = new Time();
5298                 tobj.set(System.currentTimeMillis());
5299                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5300                 sb.append(": ");
5301                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5302                 sb.append(" since ");
5303                 sb.append(msg);
5304                 FileOutputStream fos = new FileOutputStream(tracesFile);
5305                 fos.write(sb.toString().getBytes());
5306                 if (app == null) {
5307                     fos.write("\n*** No application process!".getBytes());
5308                 }
5309                 fos.close();
5310                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311             } catch (IOException e) {
5312                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5313                 return;
5314             }
5315
5316             if (app != null) {
5317                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5318                 firstPids.add(app.pid);
5319                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5320             }
5321
5322             File lastTracesFile = null;
5323             File curTracesFile = null;
5324             for (int i=9; i>=0; i--) {
5325                 String name = String.format(Locale.US, "slow%02d.txt", i);
5326                 curTracesFile = new File(tracesDir, name);
5327                 if (curTracesFile.exists()) {
5328                     if (lastTracesFile != null) {
5329                         curTracesFile.renameTo(lastTracesFile);
5330                     } else {
5331                         curTracesFile.delete();
5332                     }
5333                 }
5334                 lastTracesFile = curTracesFile;
5335             }
5336             tracesFile.renameTo(curTracesFile);
5337             if (tracesTmp.exists()) {
5338                 tracesTmp.renameTo(tracesFile);
5339             }
5340         } finally {
5341             StrictMode.setThreadPolicy(oldPolicy);
5342         }
5343     }
5344
5345     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5346         if (!mLaunchWarningShown) {
5347             mLaunchWarningShown = true;
5348             mUiHandler.post(new Runnable() {
5349                 @Override
5350                 public void run() {
5351                     synchronized (ActivityManagerService.this) {
5352                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5353                         d.show();
5354                         mUiHandler.postDelayed(new Runnable() {
5355                             @Override
5356                             public void run() {
5357                                 synchronized (ActivityManagerService.this) {
5358                                     d.dismiss();
5359                                     mLaunchWarningShown = false;
5360                                 }
5361                             }
5362                         }, 4000);
5363                     }
5364                 }
5365             });
5366         }
5367     }
5368
5369     @Override
5370     public boolean clearApplicationUserData(final String packageName,
5371             final IPackageDataObserver observer, int userId) {
5372         enforceNotIsolatedCaller("clearApplicationUserData");
5373         int uid = Binder.getCallingUid();
5374         int pid = Binder.getCallingPid();
5375         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5376                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5377
5378         final DevicePolicyManagerInternal dpmi = LocalServices
5379                 .getService(DevicePolicyManagerInternal.class);
5380         if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5381             throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5382         }
5383
5384         long callingId = Binder.clearCallingIdentity();
5385         try {
5386             IPackageManager pm = AppGlobals.getPackageManager();
5387             int pkgUid = -1;
5388             synchronized(this) {
5389                 try {
5390                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5391                 } catch (RemoteException e) {
5392                 }
5393                 if (pkgUid == -1) {
5394                     Slog.w(TAG, "Invalid packageName: " + packageName);
5395                     if (observer != null) {
5396                         try {
5397                             observer.onRemoveCompleted(packageName, false);
5398                         } catch (RemoteException e) {
5399                             Slog.i(TAG, "Observer no longer exists.");
5400                         }
5401                     }
5402                     return false;
5403                 }
5404                 if (uid == pkgUid || checkComponentPermission(
5405                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5406                         pid, uid, -1, true)
5407                         == PackageManager.PERMISSION_GRANTED) {
5408                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5409                 } else {
5410                     throw new SecurityException("PID " + pid + " does not have permission "
5411                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5412                                     + " of package " + packageName);
5413                 }
5414
5415                 // Remove all tasks match the cleared application package and user
5416                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5417                     final TaskRecord tr = mRecentTasks.get(i);
5418                     final String taskPackageName =
5419                             tr.getBaseIntent().getComponent().getPackageName();
5420                     if (tr.userId != userId) continue;
5421                     if (!taskPackageName.equals(packageName)) continue;
5422                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5423                 }
5424             }
5425
5426             final int pkgUidF = pkgUid;
5427             final int userIdF = userId;
5428             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5429                 @Override
5430                 public void onRemoveCompleted(String packageName, boolean succeeded)
5431                         throws RemoteException {
5432                     synchronized (ActivityManagerService.this) {
5433                         finishForceStopPackageLocked(packageName, pkgUidF);
5434                     }
5435
5436                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437                             Uri.fromParts("package", packageName, null));
5438                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5439                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5440                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441                             null, null, 0, null, null, null, null, false, false, userIdF);
5442
5443                     if (observer != null) {
5444                         observer.onRemoveCompleted(packageName, succeeded);
5445                     }
5446                 }
5447             };
5448
5449             try {
5450                 // Clear application user data
5451                 pm.clearApplicationUserData(packageName, localObserver, userId);
5452
5453                 synchronized(this) {
5454                     // Remove all permissions granted from/to this package
5455                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5456                 }
5457
5458                 // Remove all zen rules created by this package; revoke it's zen access.
5459                 INotificationManager inm = NotificationManager.getService();
5460                 inm.removeAutomaticZenRules(packageName);
5461                 inm.setNotificationPolicyAccessGranted(packageName, false);
5462
5463             } catch (RemoteException e) {
5464             }
5465         } finally {
5466             Binder.restoreCallingIdentity(callingId);
5467         }
5468         return true;
5469     }
5470
5471     @Override
5472     public void killBackgroundProcesses(final String packageName, int userId) {
5473         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5474                 != PackageManager.PERMISSION_GRANTED &&
5475                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5476                         != PackageManager.PERMISSION_GRANTED) {
5477             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5478                     + Binder.getCallingPid()
5479                     + ", uid=" + Binder.getCallingUid()
5480                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5481             Slog.w(TAG, msg);
5482             throw new SecurityException(msg);
5483         }
5484
5485         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5486                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5487         long callingId = Binder.clearCallingIdentity();
5488         try {
5489             IPackageManager pm = AppGlobals.getPackageManager();
5490             synchronized(this) {
5491                 int appId = -1;
5492                 try {
5493                     appId = UserHandle.getAppId(
5494                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5495                 } catch (RemoteException e) {
5496                 }
5497                 if (appId == -1) {
5498                     Slog.w(TAG, "Invalid packageName: " + packageName);
5499                     return;
5500                 }
5501                 killPackageProcessesLocked(packageName, appId, userId,
5502                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5503             }
5504         } finally {
5505             Binder.restoreCallingIdentity(callingId);
5506         }
5507     }
5508
5509     @Override
5510     public void killAllBackgroundProcesses() {
5511         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5512                 != PackageManager.PERMISSION_GRANTED) {
5513             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5514                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5515                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5516             Slog.w(TAG, msg);
5517             throw new SecurityException(msg);
5518         }
5519
5520         final long callingId = Binder.clearCallingIdentity();
5521         try {
5522             synchronized (this) {
5523                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5524                 final int NP = mProcessNames.getMap().size();
5525                 for (int ip = 0; ip < NP; ip++) {
5526                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5527                     final int NA = apps.size();
5528                     for (int ia = 0; ia < NA; ia++) {
5529                         final ProcessRecord app = apps.valueAt(ia);
5530                         if (app.persistent) {
5531                             // We don't kill persistent processes.
5532                             continue;
5533                         }
5534                         if (app.removed) {
5535                             procs.add(app);
5536                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5537                             app.removed = true;
5538                             procs.add(app);
5539                         }
5540                     }
5541                 }
5542
5543                 final int N = procs.size();
5544                 for (int i = 0; i < N; i++) {
5545                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5546                 }
5547
5548                 mAllowLowerMemLevel = true;
5549
5550                 updateOomAdjLocked();
5551                 doLowMemReportIfNeededLocked(null);
5552             }
5553         } finally {
5554             Binder.restoreCallingIdentity(callingId);
5555         }
5556     }
5557
5558     /**
5559      * Kills all background processes, except those matching any of the
5560      * specified properties.
5561      *
5562      * @param minTargetSdk the target SDK version at or above which to preserve
5563      *                     processes, or {@code -1} to ignore the target SDK
5564      * @param maxProcState the process state at or below which to preserve
5565      *                     processes, or {@code -1} to ignore the process state
5566      */
5567     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5568         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5569                 != PackageManager.PERMISSION_GRANTED) {
5570             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5571                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5572                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5573             Slog.w(TAG, msg);
5574             throw new SecurityException(msg);
5575         }
5576
5577         final long callingId = Binder.clearCallingIdentity();
5578         try {
5579             synchronized (this) {
5580                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5581                 final int NP = mProcessNames.getMap().size();
5582                 for (int ip = 0; ip < NP; ip++) {
5583                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584                     final int NA = apps.size();
5585                     for (int ia = 0; ia < NA; ia++) {
5586                         final ProcessRecord app = apps.valueAt(ia);
5587                         if (app.removed) {
5588                             procs.add(app);
5589                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5590                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5591                             app.removed = true;
5592                             procs.add(app);
5593                         }
5594                     }
5595                 }
5596
5597                 final int N = procs.size();
5598                 for (int i = 0; i < N; i++) {
5599                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5600                 }
5601             }
5602         } finally {
5603             Binder.restoreCallingIdentity(callingId);
5604         }
5605     }
5606
5607     @Override
5608     public void forceStopPackage(final String packageName, int userId) {
5609         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5610                 != PackageManager.PERMISSION_GRANTED) {
5611             String msg = "Permission Denial: forceStopPackage() from pid="
5612                     + Binder.getCallingPid()
5613                     + ", uid=" + Binder.getCallingUid()
5614                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5615             Slog.w(TAG, msg);
5616             throw new SecurityException(msg);
5617         }
5618         final int callingPid = Binder.getCallingPid();
5619         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5620                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5621         long callingId = Binder.clearCallingIdentity();
5622         try {
5623             IPackageManager pm = AppGlobals.getPackageManager();
5624             synchronized(this) {
5625                 int[] users = userId == UserHandle.USER_ALL
5626                         ? mUserController.getUsers() : new int[] { userId };
5627                 for (int user : users) {
5628                     int pkgUid = -1;
5629                     try {
5630                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5631                                 user);
5632                     } catch (RemoteException e) {
5633                     }
5634                     if (pkgUid == -1) {
5635                         Slog.w(TAG, "Invalid packageName: " + packageName);
5636                         continue;
5637                     }
5638                     try {
5639                         pm.setPackageStoppedState(packageName, true, user);
5640                     } catch (RemoteException e) {
5641                     } catch (IllegalArgumentException e) {
5642                         Slog.w(TAG, "Failed trying to unstop package "
5643                                 + packageName + ": " + e);
5644                     }
5645                     if (mUserController.isUserRunningLocked(user, 0)) {
5646                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5647                         finishForceStopPackageLocked(packageName, pkgUid);
5648                     }
5649                 }
5650             }
5651         } finally {
5652             Binder.restoreCallingIdentity(callingId);
5653         }
5654     }
5655
5656     @Override
5657     public void addPackageDependency(String packageName) {
5658         synchronized (this) {
5659             int callingPid = Binder.getCallingPid();
5660             if (callingPid == Process.myPid()) {
5661                 //  Yeah, um, no.
5662                 return;
5663             }
5664             ProcessRecord proc;
5665             synchronized (mPidsSelfLocked) {
5666                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5667             }
5668             if (proc != null) {
5669                 if (proc.pkgDeps == null) {
5670                     proc.pkgDeps = new ArraySet<String>(1);
5671                 }
5672                 proc.pkgDeps.add(packageName);
5673             }
5674         }
5675     }
5676
5677     /*
5678      * The pkg name and app id have to be specified.
5679      */
5680     @Override
5681     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5682         if (pkg == null) {
5683             return;
5684         }
5685         // Make sure the uid is valid.
5686         if (appid < 0) {
5687             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5688             return;
5689         }
5690         int callerUid = Binder.getCallingUid();
5691         // Only the system server can kill an application
5692         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5693             // Post an aysnc message to kill the application
5694             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5695             msg.arg1 = appid;
5696             msg.arg2 = 0;
5697             Bundle bundle = new Bundle();
5698             bundle.putString("pkg", pkg);
5699             bundle.putString("reason", reason);
5700             msg.obj = bundle;
5701             mHandler.sendMessage(msg);
5702         } else {
5703             throw new SecurityException(callerUid + " cannot kill pkg: " +
5704                     pkg);
5705         }
5706     }
5707
5708     @Override
5709     public void closeSystemDialogs(String reason) {
5710         enforceNotIsolatedCaller("closeSystemDialogs");
5711
5712         final int pid = Binder.getCallingPid();
5713         final int uid = Binder.getCallingUid();
5714         final long origId = Binder.clearCallingIdentity();
5715         try {
5716             synchronized (this) {
5717                 // Only allow this from foreground processes, so that background
5718                 // applications can't abuse it to prevent system UI from being shown.
5719                 if (uid >= Process.FIRST_APPLICATION_UID) {
5720                     ProcessRecord proc;
5721                     synchronized (mPidsSelfLocked) {
5722                         proc = mPidsSelfLocked.get(pid);
5723                     }
5724                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5725                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5726                                 + " from background process " + proc);
5727                         return;
5728                     }
5729                 }
5730                 closeSystemDialogsLocked(reason);
5731             }
5732         } finally {
5733             Binder.restoreCallingIdentity(origId);
5734         }
5735     }
5736
5737     void closeSystemDialogsLocked(String reason) {
5738         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5739         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5740                 | Intent.FLAG_RECEIVER_FOREGROUND);
5741         if (reason != null) {
5742             intent.putExtra("reason", reason);
5743         }
5744         mWindowManager.closeSystemDialogs(reason);
5745
5746         mStackSupervisor.closeSystemDialogsLocked();
5747
5748         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5749                 AppOpsManager.OP_NONE, null, false, false,
5750                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5751     }
5752
5753     @Override
5754     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5755         enforceNotIsolatedCaller("getProcessMemoryInfo");
5756         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5757         for (int i=pids.length-1; i>=0; i--) {
5758             ProcessRecord proc;
5759             int oomAdj;
5760             synchronized (this) {
5761                 synchronized (mPidsSelfLocked) {
5762                     proc = mPidsSelfLocked.get(pids[i]);
5763                     oomAdj = proc != null ? proc.setAdj : 0;
5764                 }
5765             }
5766             infos[i] = new Debug.MemoryInfo();
5767             Debug.getMemoryInfo(pids[i], infos[i]);
5768             if (proc != null) {
5769                 synchronized (this) {
5770                     if (proc.thread != null && proc.setAdj == oomAdj) {
5771                         // Record this for posterity if the process has been stable.
5772                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5773                                 infos[i].getTotalUss(), false, proc.pkgList);
5774                     }
5775                 }
5776             }
5777         }
5778         return infos;
5779     }
5780
5781     @Override
5782     public long[] getProcessPss(int[] pids) {
5783         enforceNotIsolatedCaller("getProcessPss");
5784         long[] pss = new long[pids.length];
5785         for (int i=pids.length-1; i>=0; i--) {
5786             ProcessRecord proc;
5787             int oomAdj;
5788             synchronized (this) {
5789                 synchronized (mPidsSelfLocked) {
5790                     proc = mPidsSelfLocked.get(pids[i]);
5791                     oomAdj = proc != null ? proc.setAdj : 0;
5792                 }
5793             }
5794             long[] tmpUss = new long[1];
5795             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5796             if (proc != null) {
5797                 synchronized (this) {
5798                     if (proc.thread != null && proc.setAdj == oomAdj) {
5799                         // Record this for posterity if the process has been stable.
5800                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5801                     }
5802                 }
5803             }
5804         }
5805         return pss;
5806     }
5807
5808     @Override
5809     public void killApplicationProcess(String processName, int uid) {
5810         if (processName == null) {
5811             return;
5812         }
5813
5814         int callerUid = Binder.getCallingUid();
5815         // Only the system server can kill an application
5816         if (callerUid == Process.SYSTEM_UID) {
5817             synchronized (this) {
5818                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5819                 if (app != null && app.thread != null) {
5820                     try {
5821                         app.thread.scheduleSuicide();
5822                     } catch (RemoteException e) {
5823                         // If the other end already died, then our work here is done.
5824                     }
5825                 } else {
5826                     Slog.w(TAG, "Process/uid not found attempting kill of "
5827                             + processName + " / " + uid);
5828                 }
5829             }
5830         } else {
5831             throw new SecurityException(callerUid + " cannot kill app process: " +
5832                     processName);
5833         }
5834     }
5835
5836     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5837         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5838                 false, true, false, false, UserHandle.getUserId(uid), reason);
5839     }
5840
5841     private void finishForceStopPackageLocked(final String packageName, int uid) {
5842         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5843                 Uri.fromParts("package", packageName, null));
5844         if (!mProcessesReady) {
5845             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5846                     | Intent.FLAG_RECEIVER_FOREGROUND);
5847         }
5848         intent.putExtra(Intent.EXTRA_UID, uid);
5849         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5850         broadcastIntentLocked(null, null, intent,
5851                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5852                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5853     }
5854
5855
5856     private final boolean killPackageProcessesLocked(String packageName, int appId,
5857             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5858             boolean doit, boolean evenPersistent, String reason) {
5859         ArrayList<ProcessRecord> procs = new ArrayList<>();
5860
5861         // Remove all processes this package may have touched: all with the
5862         // same UID (except for the system or root user), and all whose name
5863         // matches the package name.
5864         final int NP = mProcessNames.getMap().size();
5865         for (int ip=0; ip<NP; ip++) {
5866             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5867             final int NA = apps.size();
5868             for (int ia=0; ia<NA; ia++) {
5869                 ProcessRecord app = apps.valueAt(ia);
5870                 if (app.persistent && !evenPersistent) {
5871                     // we don't kill persistent processes
5872                     continue;
5873                 }
5874                 if (app.removed) {
5875                     if (doit) {
5876                         procs.add(app);
5877                     }
5878                     continue;
5879                 }
5880
5881                 // Skip process if it doesn't meet our oom adj requirement.
5882                 if (app.setAdj < minOomAdj) {
5883                     continue;
5884                 }
5885
5886                 // If no package is specified, we call all processes under the
5887                 // give user id.
5888                 if (packageName == null) {
5889                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5890                         continue;
5891                     }
5892                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5893                         continue;
5894                     }
5895                 // Package has been specified, we want to hit all processes
5896                 // that match it.  We need to qualify this by the processes
5897                 // that are running under the specified app and user ID.
5898                 } else {
5899                     final boolean isDep = app.pkgDeps != null
5900                             && app.pkgDeps.contains(packageName);
5901                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5902                         continue;
5903                     }
5904                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5905                         continue;
5906                     }
5907                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5908                         continue;
5909                     }
5910                 }
5911
5912                 // Process has passed all conditions, kill it!
5913                 if (!doit) {
5914                     return true;
5915                 }
5916                 app.removed = true;
5917                 procs.add(app);
5918             }
5919         }
5920
5921         int N = procs.size();
5922         for (int i=0; i<N; i++) {
5923             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5924         }
5925         updateOomAdjLocked();
5926         return N > 0;
5927     }
5928
5929     private void cleanupDisabledPackageComponentsLocked(
5930             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5931
5932         Set<String> disabledClasses = null;
5933         boolean packageDisabled = false;
5934         IPackageManager pm = AppGlobals.getPackageManager();
5935
5936         if (changedClasses == null) {
5937             // Nothing changed...
5938             return;
5939         }
5940
5941         // Determine enable/disable state of the package and its components.
5942         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5943         for (int i = changedClasses.length - 1; i >= 0; i--) {
5944             final String changedClass = changedClasses[i];
5945
5946             if (changedClass.equals(packageName)) {
5947                 try {
5948                     // Entire package setting changed
5949                     enabled = pm.getApplicationEnabledSetting(packageName,
5950                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5951                 } catch (Exception e) {
5952                     // No such package/component; probably racing with uninstall.  In any
5953                     // event it means we have nothing further to do here.
5954                     return;
5955                 }
5956                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5957                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5958                 if (packageDisabled) {
5959                     // Entire package is disabled.
5960                     // No need to continue to check component states.
5961                     disabledClasses = null;
5962                     break;
5963                 }
5964             } else {
5965                 try {
5966                     enabled = pm.getComponentEnabledSetting(
5967                             new ComponentName(packageName, changedClass),
5968                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5969                 } catch (Exception e) {
5970                     // As above, probably racing with uninstall.
5971                     return;
5972                 }
5973                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5974                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5975                     if (disabledClasses == null) {
5976                         disabledClasses = new ArraySet<>(changedClasses.length);
5977                     }
5978                     disabledClasses.add(changedClass);
5979                 }
5980             }
5981         }
5982
5983         if (!packageDisabled && disabledClasses == null) {
5984             // Nothing to do here...
5985             return;
5986         }
5987
5988         // Clean-up disabled activities.
5989         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5990                 packageName, disabledClasses, true, false, userId) && mBooted) {
5991             mStackSupervisor.resumeFocusedStackTopActivityLocked();
5992             mStackSupervisor.scheduleIdleLocked();
5993         }
5994
5995         // Clean-up disabled tasks
5996         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5997
5998         // Clean-up disabled services.
5999         mServices.bringDownDisabledPackageServicesLocked(
6000                 packageName, disabledClasses, userId, false, killProcess, true);
6001
6002         // Clean-up disabled providers.
6003         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6004         mProviderMap.collectPackageProvidersLocked(
6005                 packageName, disabledClasses, true, false, userId, providers);
6006         for (int i = providers.size() - 1; i >= 0; i--) {
6007             removeDyingProviderLocked(null, providers.get(i), true);
6008         }
6009
6010         // Clean-up disabled broadcast receivers.
6011         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6012             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6013                     packageName, disabledClasses, userId, true);
6014         }
6015
6016     }
6017
6018     final boolean clearBroadcastQueueForUserLocked(int userId) {
6019         boolean didSomething = false;
6020         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                     null, null, userId, true);
6023         }
6024         return didSomething;
6025     }
6026
6027     final boolean forceStopPackageLocked(String packageName, int appId,
6028             boolean callerWillRestart, boolean purgeCache, boolean doit,
6029             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6030         int i;
6031
6032         if (userId == UserHandle.USER_ALL && packageName == null) {
6033             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6034         }
6035
6036         if (appId < 0 && packageName != null) {
6037             try {
6038                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6039                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6040             } catch (RemoteException e) {
6041             }
6042         }
6043
6044         if (doit) {
6045             if (packageName != null) {
6046                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6047                         + " user=" + userId + ": " + reason);
6048             } else {
6049                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6050             }
6051
6052             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6053         }
6054
6055         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6056                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6057                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6058
6059         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6060                 packageName, null, doit, evenPersistent, userId)) {
6061             if (!doit) {
6062                 return true;
6063             }
6064             didSomething = true;
6065         }
6066
6067         if (mServices.bringDownDisabledPackageServicesLocked(
6068                 packageName, null, userId, evenPersistent, true, doit)) {
6069             if (!doit) {
6070                 return true;
6071             }
6072             didSomething = true;
6073         }
6074
6075         if (packageName == null) {
6076             // Remove all sticky broadcasts from this user.
6077             mStickyBroadcasts.remove(userId);
6078         }
6079
6080         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6081         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6082                 userId, providers)) {
6083             if (!doit) {
6084                 return true;
6085             }
6086             didSomething = true;
6087         }
6088         for (i = providers.size() - 1; i >= 0; i--) {
6089             removeDyingProviderLocked(null, providers.get(i), true);
6090         }
6091
6092         // Remove transient permissions granted from/to this package/user
6093         removeUriPermissionsForPackageLocked(packageName, userId, false);
6094
6095         if (doit) {
6096             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6097                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6098                         packageName, null, userId, doit);
6099             }
6100         }
6101
6102         if (packageName == null || uninstalling) {
6103             // Remove pending intents.  For now we only do this when force
6104             // stopping users, because we have some problems when doing this
6105             // for packages -- app widgets are not currently cleaned up for
6106             // such packages, so they can be left with bad pending intents.
6107             if (mIntentSenderRecords.size() > 0) {
6108                 Iterator<WeakReference<PendingIntentRecord>> it
6109                         = mIntentSenderRecords.values().iterator();
6110                 while (it.hasNext()) {
6111                     WeakReference<PendingIntentRecord> wpir = it.next();
6112                     if (wpir == null) {
6113                         it.remove();
6114                         continue;
6115                     }
6116                     PendingIntentRecord pir = wpir.get();
6117                     if (pir == null) {
6118                         it.remove();
6119                         continue;
6120                     }
6121                     if (packageName == null) {
6122                         // Stopping user, remove all objects for the user.
6123                         if (pir.key.userId != userId) {
6124                             // Not the same user, skip it.
6125                             continue;
6126                         }
6127                     } else {
6128                         if (UserHandle.getAppId(pir.uid) != appId) {
6129                             // Different app id, skip it.
6130                             continue;
6131                         }
6132                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6133                             // Different user, skip it.
6134                             continue;
6135                         }
6136                         if (!pir.key.packageName.equals(packageName)) {
6137                             // Different package, skip it.
6138                             continue;
6139                         }
6140                     }
6141                     if (!doit) {
6142                         return true;
6143                     }
6144                     didSomething = true;
6145                     it.remove();
6146                     pir.canceled = true;
6147                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6148                         pir.key.activity.pendingResults.remove(pir.ref);
6149                     }
6150                 }
6151             }
6152         }
6153
6154         if (doit) {
6155             if (purgeCache && packageName != null) {
6156                 AttributeCache ac = AttributeCache.instance();
6157                 if (ac != null) {
6158                     ac.removePackage(packageName);
6159                 }
6160             }
6161             if (mBooted) {
6162                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6163                 mStackSupervisor.scheduleIdleLocked();
6164             }
6165         }
6166
6167         return didSomething;
6168     }
6169
6170     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6171         ProcessRecord old = mProcessNames.remove(name, uid);
6172         if (old != null) {
6173             old.uidRecord.numProcs--;
6174             if (old.uidRecord.numProcs == 0) {
6175                 // No more processes using this uid, tell clients it is gone.
6176                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6177                         "No more processes in " + old.uidRecord);
6178                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6179                 mActiveUids.remove(uid);
6180                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6181             }
6182             old.uidRecord = null;
6183         }
6184         mIsolatedProcesses.remove(uid);
6185         return old;
6186     }
6187
6188     private final void addProcessNameLocked(ProcessRecord proc) {
6189         // We shouldn't already have a process under this name, but just in case we
6190         // need to clean up whatever may be there now.
6191         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6192         if (old == proc && proc.persistent) {
6193             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6194             Slog.w(TAG, "Re-adding persistent process " + proc);
6195         } else if (old != null) {
6196             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6197         }
6198         UidRecord uidRec = mActiveUids.get(proc.uid);
6199         if (uidRec == null) {
6200             uidRec = new UidRecord(proc.uid);
6201             // This is the first appearance of the uid, report it now!
6202             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6203                     "Creating new process uid: " + uidRec);
6204             mActiveUids.put(proc.uid, uidRec);
6205             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6206             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6207         }
6208         proc.uidRecord = uidRec;
6209         uidRec.numProcs++;
6210         mProcessNames.put(proc.processName, proc.uid, proc);
6211         if (proc.isolated) {
6212             mIsolatedProcesses.put(proc.uid, proc);
6213         }
6214     }
6215
6216     boolean removeProcessLocked(ProcessRecord app,
6217             boolean callerWillRestart, boolean allowRestart, String reason) {
6218         final String name = app.processName;
6219         final int uid = app.uid;
6220         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6221             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6222
6223         ProcessRecord old = mProcessNames.get(name, uid);
6224         if (old != app) {
6225             // This process is no longer active, so nothing to do.
6226             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6227             return false;
6228         }
6229         removeProcessNameLocked(name, uid);
6230         if (mHeavyWeightProcess == app) {
6231             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6232                     mHeavyWeightProcess.userId, 0));
6233             mHeavyWeightProcess = null;
6234         }
6235         boolean needRestart = false;
6236         if (app.pid > 0 && app.pid != MY_PID) {
6237             int pid = app.pid;
6238             synchronized (mPidsSelfLocked) {
6239                 mPidsSelfLocked.remove(pid);
6240                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6241             }
6242             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6243             if (app.isolated) {
6244                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6245             }
6246             boolean willRestart = false;
6247             if (app.persistent && !app.isolated) {
6248                 if (!callerWillRestart) {
6249                     willRestart = true;
6250                 } else {
6251                     needRestart = true;
6252                 }
6253             }
6254             app.kill(reason, true);
6255             handleAppDiedLocked(app, willRestart, allowRestart);
6256             if (willRestart) {
6257                 removeLruProcessLocked(app);
6258                 addAppLocked(app.info, false, null /* ABI override */);
6259             }
6260         } else {
6261             mRemovedProcesses.add(app);
6262         }
6263
6264         return needRestart;
6265     }
6266
6267     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6268         cleanupAppInLaunchingProvidersLocked(app, true);
6269         removeProcessLocked(app, false, true, "timeout publishing content providers");
6270     }
6271
6272     private final void processStartTimedOutLocked(ProcessRecord app) {
6273         final int pid = app.pid;
6274         boolean gone = false;
6275         synchronized (mPidsSelfLocked) {
6276             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6277             if (knownApp != null && knownApp.thread == null) {
6278                 mPidsSelfLocked.remove(pid);
6279                 gone = true;
6280             }
6281         }
6282
6283         if (gone) {
6284             Slog.w(TAG, "Process " + app + " failed to attach");
6285             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6286                     pid, app.uid, app.processName);
6287             removeProcessNameLocked(app.processName, app.uid);
6288             if (mHeavyWeightProcess == app) {
6289                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6290                         mHeavyWeightProcess.userId, 0));
6291                 mHeavyWeightProcess = null;
6292             }
6293             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6294             if (app.isolated) {
6295                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6296             }
6297             // Take care of any launching providers waiting for this process.
6298             cleanupAppInLaunchingProvidersLocked(app, true);
6299             // Take care of any services that are waiting for the process.
6300             mServices.processStartTimedOutLocked(app);
6301             app.kill("start timeout", true);
6302             removeLruProcessLocked(app);
6303             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6304                 Slog.w(TAG, "Unattached app died before backup, skipping");
6305                 try {
6306                     IBackupManager bm = IBackupManager.Stub.asInterface(
6307                             ServiceManager.getService(Context.BACKUP_SERVICE));
6308                     bm.agentDisconnected(app.info.packageName);
6309                 } catch (RemoteException e) {
6310                     // Can't happen; the backup manager is local
6311                 }
6312             }
6313             if (isPendingBroadcastProcessLocked(pid)) {
6314                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6315                 skipPendingBroadcastLocked(pid);
6316             }
6317         } else {
6318             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6319         }
6320     }
6321
6322     private final boolean attachApplicationLocked(IApplicationThread thread,
6323             int pid) {
6324
6325         // Find the application record that is being attached...  either via
6326         // the pid if we are running in multiple processes, or just pull the
6327         // next app record if we are emulating process with anonymous threads.
6328         ProcessRecord app;
6329         if (pid != MY_PID && pid >= 0) {
6330             synchronized (mPidsSelfLocked) {
6331                 app = mPidsSelfLocked.get(pid);
6332             }
6333         } else {
6334             app = null;
6335         }
6336
6337         if (app == null) {
6338             Slog.w(TAG, "No pending application record for pid " + pid
6339                     + " (IApplicationThread " + thread + "); dropping process");
6340             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6341             if (pid > 0 && pid != MY_PID) {
6342                 Process.killProcessQuiet(pid);
6343                 //TODO: killProcessGroup(app.info.uid, pid);
6344             } else {
6345                 try {
6346                     thread.scheduleExit();
6347                 } catch (Exception e) {
6348                     // Ignore exceptions.
6349                 }
6350             }
6351             return false;
6352         }
6353
6354         // If this application record is still attached to a previous
6355         // process, clean it up now.
6356         if (app.thread != null) {
6357             handleAppDiedLocked(app, true, true);
6358         }
6359
6360         // Tell the process all about itself.
6361
6362         if (DEBUG_ALL) Slog.v(
6363                 TAG, "Binding process pid " + pid + " to record " + app);
6364
6365         final String processName = app.processName;
6366         try {
6367             AppDeathRecipient adr = new AppDeathRecipient(
6368                     app, pid, thread);
6369             thread.asBinder().linkToDeath(adr, 0);
6370             app.deathRecipient = adr;
6371         } catch (RemoteException e) {
6372             app.resetPackageList(mProcessStats);
6373             startProcessLocked(app, "link fail", processName);
6374             return false;
6375         }
6376
6377         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6378
6379         app.makeActive(thread, mProcessStats);
6380         app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6381         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6382         app.forcingToForeground = null;
6383         updateProcessForegroundLocked(app, false, false);
6384         app.hasShownUi = false;
6385         app.debugging = false;
6386         app.cached = false;
6387         app.killedByAm = false;
6388
6389         // We carefully use the same state that PackageManager uses for
6390         // filtering, since we use this flag to decide if we need to install
6391         // providers when user is unlocked later
6392         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6393
6394         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6395
6396         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6397         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6398
6399         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6400             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6401             msg.obj = app;
6402             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6403         }
6404
6405         if (!normalMode) {
6406             Slog.i(TAG, "Launching preboot mode app: " + app);
6407         }
6408
6409         if (DEBUG_ALL) Slog.v(
6410             TAG, "New app record " + app
6411             + " thread=" + thread.asBinder() + " pid=" + pid);
6412         try {
6413             int testMode = IApplicationThread.DEBUG_OFF;
6414             if (mDebugApp != null && mDebugApp.equals(processName)) {
6415                 testMode = mWaitForDebugger
6416                     ? IApplicationThread.DEBUG_WAIT
6417                     : IApplicationThread.DEBUG_ON;
6418                 app.debugging = true;
6419                 if (mDebugTransient) {
6420                     mDebugApp = mOrigDebugApp;
6421                     mWaitForDebugger = mOrigWaitForDebugger;
6422                 }
6423             }
6424             String profileFile = app.instrumentationProfileFile;
6425             ParcelFileDescriptor profileFd = null;
6426             int samplingInterval = 0;
6427             boolean profileAutoStop = false;
6428             if (mProfileApp != null && mProfileApp.equals(processName)) {
6429                 mProfileProc = app;
6430                 profileFile = mProfileFile;
6431                 profileFd = mProfileFd;
6432                 samplingInterval = mSamplingInterval;
6433                 profileAutoStop = mAutoStopProfiler;
6434             }
6435             boolean enableTrackAllocation = false;
6436             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6437                 enableTrackAllocation = true;
6438                 mTrackAllocationApp = null;
6439             }
6440
6441             // If the app is being launched for restore or full backup, set it up specially
6442             boolean isRestrictedBackupMode = false;
6443             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6444                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6445                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6446                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6447                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6448             }
6449
6450             if (app.instrumentationClass != null) {
6451                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6452                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6453             }
6454             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6455                     + processName + " with config " + mConfiguration);
6456             ApplicationInfo appInfo = app.instrumentationInfo != null
6457                     ? app.instrumentationInfo : app.info;
6458             app.compat = compatibilityInfoForPackageLocked(appInfo);
6459             if (profileFd != null) {
6460                 profileFd = profileFd.dup();
6461             }
6462             ProfilerInfo profilerInfo = profileFile == null ? null
6463                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6464             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6465                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6466                     app.instrumentationUiAutomationConnection, testMode,
6467                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6468                     isRestrictedBackupMode || !normalMode, app.persistent,
6469                     new Configuration(mConfiguration), app.compat,
6470                     getCommonServicesLocked(app.isolated),
6471                     mCoreSettingsObserver.getCoreSettingsLocked());
6472             updateLruProcessLocked(app, false, null);
6473             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6474         } catch (Exception e) {
6475             // todo: Yikes!  What should we do?  For now we will try to
6476             // start another process, but that could easily get us in
6477             // an infinite loop of restarting processes...
6478             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6479
6480             app.resetPackageList(mProcessStats);
6481             app.unlinkDeathRecipient();
6482             startProcessLocked(app, "bind fail", processName);
6483             return false;
6484         }
6485
6486         // Remove this record from the list of starting applications.
6487         mPersistentStartingProcesses.remove(app);
6488         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6489                 "Attach application locked removing on hold: " + app);
6490         mProcessesOnHold.remove(app);
6491
6492         boolean badApp = false;
6493         boolean didSomething = false;
6494
6495         // See if the top visible activity is waiting to run in this process...
6496         if (normalMode) {
6497             try {
6498                 if (mStackSupervisor.attachApplicationLocked(app)) {
6499                     didSomething = true;
6500                 }
6501             } catch (Exception e) {
6502                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6503                 badApp = true;
6504             }
6505         }
6506
6507         // Find any services that should be running in this process...
6508         if (!badApp) {
6509             try {
6510                 didSomething |= mServices.attachApplicationLocked(app, processName);
6511             } catch (Exception e) {
6512                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6513                 badApp = true;
6514             }
6515         }
6516
6517         // Check if a next-broadcast receiver is in this process...
6518         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6519             try {
6520                 didSomething |= sendPendingBroadcastsLocked(app);
6521             } catch (Exception e) {
6522                 // If the app died trying to launch the receiver we declare it 'bad'
6523                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6524                 badApp = true;
6525             }
6526         }
6527
6528         // Check whether the next backup agent is in this process...
6529         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6530             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6531                     "New app is backup target, launching agent for " + app);
6532             notifyPackageUse(mBackupTarget.appInfo.packageName,
6533                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6534             try {
6535                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6536                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6537                         mBackupTarget.backupMode);
6538             } catch (Exception e) {
6539                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6540                 badApp = true;
6541             }
6542         }
6543
6544         if (badApp) {
6545             app.kill("error during init", true);
6546             handleAppDiedLocked(app, false, true);
6547             return false;
6548         }
6549
6550         if (!didSomething) {
6551             updateOomAdjLocked();
6552         }
6553
6554         return true;
6555     }
6556
6557     @Override
6558     public final void attachApplication(IApplicationThread thread) {
6559         synchronized (this) {
6560             int callingPid = Binder.getCallingPid();
6561             final long origId = Binder.clearCallingIdentity();
6562             attachApplicationLocked(thread, callingPid);
6563             Binder.restoreCallingIdentity(origId);
6564         }
6565     }
6566
6567     @Override
6568     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6569         final long origId = Binder.clearCallingIdentity();
6570         synchronized (this) {
6571             ActivityStack stack = ActivityRecord.getStackLocked(token);
6572             if (stack != null) {
6573                 ActivityRecord r =
6574                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6575                 if (stopProfiling) {
6576                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6577                         try {
6578                             mProfileFd.close();
6579                         } catch (IOException e) {
6580                         }
6581                         clearProfilerLocked();
6582                     }
6583                 }
6584             }
6585         }
6586         Binder.restoreCallingIdentity(origId);
6587     }
6588
6589     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6590         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6591                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6592     }
6593
6594     void enableScreenAfterBoot() {
6595         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6596                 SystemClock.uptimeMillis());
6597         mWindowManager.enableScreenAfterBoot();
6598
6599         synchronized (this) {
6600             updateEventDispatchingLocked();
6601         }
6602     }
6603
6604     @Override
6605     public void showBootMessage(final CharSequence msg, final boolean always) {
6606         if (Binder.getCallingUid() != Process.myUid()) {
6607             // These days only the core system can call this, so apps can't get in
6608             // the way of what we show about running them.
6609         }
6610         mWindowManager.showBootMessage(msg, always);
6611     }
6612
6613     @Override
6614     public void keyguardWaitingForActivityDrawn() {
6615         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6616         final long token = Binder.clearCallingIdentity();
6617         try {
6618             synchronized (this) {
6619                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6620                 mWindowManager.keyguardWaitingForActivityDrawn();
6621                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6622                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6623                     updateSleepIfNeededLocked();
6624                 }
6625             }
6626         } finally {
6627             Binder.restoreCallingIdentity(token);
6628         }
6629     }
6630
6631     @Override
6632     public void keyguardGoingAway(int flags) {
6633         enforceNotIsolatedCaller("keyguardGoingAway");
6634         final long token = Binder.clearCallingIdentity();
6635         try {
6636             synchronized (this) {
6637                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6638                 mWindowManager.keyguardGoingAway(flags);
6639                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6640                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6641                     updateSleepIfNeededLocked();
6642
6643                     // Some stack visibility might change (e.g. docked stack)
6644                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6645                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6646                 }
6647             }
6648         } finally {
6649             Binder.restoreCallingIdentity(token);
6650         }
6651     }
6652
6653     final void finishBooting() {
6654         synchronized (this) {
6655             if (!mBootAnimationComplete) {
6656                 mCallFinishBooting = true;
6657                 return;
6658             }
6659             mCallFinishBooting = false;
6660         }
6661
6662         ArraySet<String> completedIsas = new ArraySet<String>();
6663         for (String abi : Build.SUPPORTED_ABIS) {
6664             Process.establishZygoteConnectionForAbi(abi);
6665             final String instructionSet = VMRuntime.getInstructionSet(abi);
6666             if (!completedIsas.contains(instructionSet)) {
6667                 try {
6668                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6669                 } catch (InstallerException e) {
6670                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6671                             e.getMessage() +")");
6672                 }
6673                 completedIsas.add(instructionSet);
6674             }
6675         }
6676
6677         IntentFilter pkgFilter = new IntentFilter();
6678         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6679         pkgFilter.addDataScheme("package");
6680         mContext.registerReceiver(new BroadcastReceiver() {
6681             @Override
6682             public void onReceive(Context context, Intent intent) {
6683                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6684                 if (pkgs != null) {
6685                     for (String pkg : pkgs) {
6686                         synchronized (ActivityManagerService.this) {
6687                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6688                                     0, "query restart")) {
6689                                 setResultCode(Activity.RESULT_OK);
6690                                 return;
6691                             }
6692                         }
6693                     }
6694                 }
6695             }
6696         }, pkgFilter);
6697
6698         IntentFilter dumpheapFilter = new IntentFilter();
6699         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6700         mContext.registerReceiver(new BroadcastReceiver() {
6701             @Override
6702             public void onReceive(Context context, Intent intent) {
6703                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6704                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6705                 } else {
6706                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6707                 }
6708             }
6709         }, dumpheapFilter);
6710
6711         // Let system services know.
6712         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6713
6714         synchronized (this) {
6715             // Ensure that any processes we had put on hold are now started
6716             // up.
6717             final int NP = mProcessesOnHold.size();
6718             if (NP > 0) {
6719                 ArrayList<ProcessRecord> procs =
6720                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6721                 for (int ip=0; ip<NP; ip++) {
6722                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6723                             + procs.get(ip));
6724                     startProcessLocked(procs.get(ip), "on-hold", null);
6725                 }
6726             }
6727
6728             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6729                 // Start looking for apps that are abusing wake locks.
6730                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6731                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6732                 // Tell anyone interested that we are done booting!
6733                 SystemProperties.set("sys.boot_completed", "1");
6734
6735                 // And trigger dev.bootcomplete if we are not showing encryption progress
6736                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6737                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6738                     SystemProperties.set("dev.bootcomplete", "1");
6739                 }
6740                 mUserController.sendBootCompletedLocked(
6741                         new IIntentReceiver.Stub() {
6742                             @Override
6743                             public void performReceive(Intent intent, int resultCode,
6744                                     String data, Bundle extras, boolean ordered,
6745                                     boolean sticky, int sendingUser) {
6746                                 synchronized (ActivityManagerService.this) {
6747                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6748                                             true, false);
6749                                 }
6750                             }
6751                         });
6752                 scheduleStartProfilesLocked();
6753             }
6754         }
6755     }
6756
6757     @Override
6758     public void bootAnimationComplete() {
6759         final boolean callFinishBooting;
6760         synchronized (this) {
6761             callFinishBooting = mCallFinishBooting;
6762             mBootAnimationComplete = true;
6763         }
6764         if (callFinishBooting) {
6765             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6766             finishBooting();
6767             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6768         }
6769     }
6770
6771     final void ensureBootCompleted() {
6772         boolean booting;
6773         boolean enableScreen;
6774         synchronized (this) {
6775             booting = mBooting;
6776             mBooting = false;
6777             enableScreen = !mBooted;
6778             mBooted = true;
6779         }
6780
6781         if (booting) {
6782             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6783             finishBooting();
6784             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6785         }
6786
6787         if (enableScreen) {
6788             enableScreenAfterBoot();
6789         }
6790     }
6791
6792     @Override
6793     public final void activityResumed(IBinder token) {
6794         final long origId = Binder.clearCallingIdentity();
6795         synchronized(this) {
6796             ActivityStack stack = ActivityRecord.getStackLocked(token);
6797             if (stack != null) {
6798                 stack.activityResumedLocked(token);
6799             }
6800         }
6801         Binder.restoreCallingIdentity(origId);
6802     }
6803
6804     @Override
6805     public final void activityPaused(IBinder token) {
6806         final long origId = Binder.clearCallingIdentity();
6807         synchronized(this) {
6808             ActivityStack stack = ActivityRecord.getStackLocked(token);
6809             if (stack != null) {
6810                 stack.activityPausedLocked(token, false);
6811             }
6812         }
6813         Binder.restoreCallingIdentity(origId);
6814     }
6815
6816     @Override
6817     public final void activityStopped(IBinder token, Bundle icicle,
6818             PersistableBundle persistentState, CharSequence description) {
6819         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6820
6821         // Refuse possible leaked file descriptors
6822         if (icicle != null && icicle.hasFileDescriptors()) {
6823             throw new IllegalArgumentException("File descriptors passed in Bundle");
6824         }
6825
6826         final long origId = Binder.clearCallingIdentity();
6827
6828         synchronized (this) {
6829             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830             if (r != null) {
6831                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6832             }
6833         }
6834
6835         trimApplications();
6836
6837         Binder.restoreCallingIdentity(origId);
6838     }
6839
6840     @Override
6841     public final void activityDestroyed(IBinder token) {
6842         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6843         synchronized (this) {
6844             ActivityStack stack = ActivityRecord.getStackLocked(token);
6845             if (stack != null) {
6846                 stack.activityDestroyedLocked(token, "activityDestroyed");
6847             }
6848         }
6849     }
6850
6851     @Override
6852     public final void activityRelaunched(IBinder token) {
6853         final long origId = Binder.clearCallingIdentity();
6854         synchronized (this) {
6855             mStackSupervisor.activityRelaunchedLocked(token);
6856         }
6857         Binder.restoreCallingIdentity(origId);
6858     }
6859
6860     @Override
6861     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6862             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6863         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6864                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6865         synchronized (this) {
6866             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6867             if (record == null) {
6868                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6869                         + "found for: " + token);
6870             }
6871             record.setSizeConfigurations(horizontalSizeConfiguration,
6872                     verticalSizeConfigurations, smallestSizeConfigurations);
6873         }
6874     }
6875
6876     @Override
6877     public final void backgroundResourcesReleased(IBinder token) {
6878         final long origId = Binder.clearCallingIdentity();
6879         try {
6880             synchronized (this) {
6881                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6882                 if (stack != null) {
6883                     stack.backgroundResourcesReleased();
6884                 }
6885             }
6886         } finally {
6887             Binder.restoreCallingIdentity(origId);
6888         }
6889     }
6890
6891     @Override
6892     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6893         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6894     }
6895
6896     @Override
6897     public final void notifyEnterAnimationComplete(IBinder token) {
6898         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6899     }
6900
6901     @Override
6902     public String getCallingPackage(IBinder token) {
6903         synchronized (this) {
6904             ActivityRecord r = getCallingRecordLocked(token);
6905             return r != null ? r.info.packageName : null;
6906         }
6907     }
6908
6909     @Override
6910     public ComponentName getCallingActivity(IBinder token) {
6911         synchronized (this) {
6912             ActivityRecord r = getCallingRecordLocked(token);
6913             return r != null ? r.intent.getComponent() : null;
6914         }
6915     }
6916
6917     private ActivityRecord getCallingRecordLocked(IBinder token) {
6918         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6919         if (r == null) {
6920             return null;
6921         }
6922         return r.resultTo;
6923     }
6924
6925     @Override
6926     public ComponentName getActivityClassForToken(IBinder token) {
6927         synchronized(this) {
6928             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6929             if (r == null) {
6930                 return null;
6931             }
6932             return r.intent.getComponent();
6933         }
6934     }
6935
6936     @Override
6937     public String getPackageForToken(IBinder token) {
6938         synchronized(this) {
6939             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6940             if (r == null) {
6941                 return null;
6942             }
6943             return r.packageName;
6944         }
6945     }
6946
6947     @Override
6948     public boolean isRootVoiceInteraction(IBinder token) {
6949         synchronized(this) {
6950             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6951             if (r == null) {
6952                 return false;
6953             }
6954             return r.rootVoiceInteraction;
6955         }
6956     }
6957
6958     @Override
6959     public IIntentSender getIntentSender(int type,
6960             String packageName, IBinder token, String resultWho,
6961             int requestCode, Intent[] intents, String[] resolvedTypes,
6962             int flags, Bundle bOptions, int userId) {
6963         enforceNotIsolatedCaller("getIntentSender");
6964         // Refuse possible leaked file descriptors
6965         if (intents != null) {
6966             if (intents.length < 1) {
6967                 throw new IllegalArgumentException("Intents array length must be >= 1");
6968             }
6969             for (int i=0; i<intents.length; i++) {
6970                 Intent intent = intents[i];
6971                 if (intent != null) {
6972                     if (intent.hasFileDescriptors()) {
6973                         throw new IllegalArgumentException("File descriptors passed in Intent");
6974                     }
6975                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6976                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6977                         throw new IllegalArgumentException(
6978                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6979                     }
6980                     intents[i] = new Intent(intent);
6981                 }
6982             }
6983             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6984                 throw new IllegalArgumentException(
6985                         "Intent array length does not match resolvedTypes length");
6986             }
6987         }
6988         if (bOptions != null) {
6989             if (bOptions.hasFileDescriptors()) {
6990                 throw new IllegalArgumentException("File descriptors passed in options");
6991             }
6992         }
6993
6994         synchronized(this) {
6995             int callingUid = Binder.getCallingUid();
6996             int origUserId = userId;
6997             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6998                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6999                     ALLOW_NON_FULL, "getIntentSender", null);
7000             if (origUserId == UserHandle.USER_CURRENT) {
7001                 // We don't want to evaluate this until the pending intent is
7002                 // actually executed.  However, we do want to always do the
7003                 // security checking for it above.
7004                 userId = UserHandle.USER_CURRENT;
7005             }
7006             try {
7007                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7008                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7009                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7010                     if (!UserHandle.isSameApp(callingUid, uid)) {
7011                         String msg = "Permission Denial: getIntentSender() from pid="
7012                             + Binder.getCallingPid()
7013                             + ", uid=" + Binder.getCallingUid()
7014                             + ", (need uid=" + uid + ")"
7015                             + " is not allowed to send as package " + packageName;
7016                         Slog.w(TAG, msg);
7017                         throw new SecurityException(msg);
7018                     }
7019                 }
7020
7021                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7022                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7023
7024             } catch (RemoteException e) {
7025                 throw new SecurityException(e);
7026             }
7027         }
7028     }
7029
7030     IIntentSender getIntentSenderLocked(int type, String packageName,
7031             int callingUid, int userId, IBinder token, String resultWho,
7032             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7033             Bundle bOptions) {
7034         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7035         ActivityRecord activity = null;
7036         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7037             activity = ActivityRecord.isInStackLocked(token);
7038             if (activity == null) {
7039                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7040                 return null;
7041             }
7042             if (activity.finishing) {
7043                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7044                 return null;
7045             }
7046         }
7047
7048         // We're going to be splicing together extras before sending, so we're
7049         // okay poking into any contained extras.
7050         if (intents != null) {
7051             for (int i = 0; i < intents.length; i++) {
7052                 intents[i].setDefusable(true);
7053             }
7054         }
7055         Bundle.setDefusable(bOptions, true);
7056
7057         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7058         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7059         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7060         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7061                 |PendingIntent.FLAG_UPDATE_CURRENT);
7062
7063         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7064                 type, packageName, activity, resultWho,
7065                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7066         WeakReference<PendingIntentRecord> ref;
7067         ref = mIntentSenderRecords.get(key);
7068         PendingIntentRecord rec = ref != null ? ref.get() : null;
7069         if (rec != null) {
7070             if (!cancelCurrent) {
7071                 if (updateCurrent) {
7072                     if (rec.key.requestIntent != null) {
7073                         rec.key.requestIntent.replaceExtras(intents != null ?
7074                                 intents[intents.length - 1] : null);
7075                     }
7076                     if (intents != null) {
7077                         intents[intents.length-1] = rec.key.requestIntent;
7078                         rec.key.allIntents = intents;
7079                         rec.key.allResolvedTypes = resolvedTypes;
7080                     } else {
7081                         rec.key.allIntents = null;
7082                         rec.key.allResolvedTypes = null;
7083                     }
7084                 }
7085                 return rec;
7086             }
7087             rec.canceled = true;
7088             mIntentSenderRecords.remove(key);
7089         }
7090         if (noCreate) {
7091             return rec;
7092         }
7093         rec = new PendingIntentRecord(this, key, callingUid);
7094         mIntentSenderRecords.put(key, rec.ref);
7095         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7096             if (activity.pendingResults == null) {
7097                 activity.pendingResults
7098                         = new HashSet<WeakReference<PendingIntentRecord>>();
7099             }
7100             activity.pendingResults.add(rec.ref);
7101         }
7102         return rec;
7103     }
7104
7105     @Override
7106     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7107             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7108         if (target instanceof PendingIntentRecord) {
7109             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7110                     finishedReceiver, requiredPermission, options);
7111         } else {
7112             if (intent == null) {
7113                 // Weird case: someone has given us their own custom IIntentSender, and now
7114                 // they have someone else trying to send to it but of course this isn't
7115                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7116                 // supplying an Intent... but we never want to dispatch a null Intent to
7117                 // a receiver, so um...  let's make something up.
7118                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7119                 intent = new Intent(Intent.ACTION_MAIN);
7120             }
7121             try {
7122                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7123             } catch (RemoteException e) {
7124             }
7125             // Platform code can rely on getting a result back when the send is done, but if
7126             // this intent sender is from outside of the system we can't rely on it doing that.
7127             // So instead we don't give it the result receiver, and instead just directly
7128             // report the finish immediately.
7129             if (finishedReceiver != null) {
7130                 try {
7131                     finishedReceiver.performReceive(intent, 0,
7132                             null, null, false, false, UserHandle.getCallingUserId());
7133                 } catch (RemoteException e) {
7134                 }
7135             }
7136             return 0;
7137         }
7138     }
7139
7140     /**
7141      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7142      *
7143      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7144      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7145      */
7146     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7147         if (DEBUG_WHITELISTS) {
7148             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7149                     + targetUid + ", " + duration + ")");
7150         }
7151         synchronized (mPidsSelfLocked) {
7152             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7153             if (pr == null) {
7154                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7155                 return;
7156             }
7157             if (!pr.whitelistManager) {
7158                 if (DEBUG_WHITELISTS) {
7159                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7160                             + callerPid + " is not allowed");
7161                 }
7162                 return;
7163             }
7164         }
7165
7166         final long token = Binder.clearCallingIdentity();
7167         try {
7168             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7169                     true, "pe from uid:" + callerUid);
7170         } finally {
7171             Binder.restoreCallingIdentity(token);
7172         }
7173     }
7174
7175     @Override
7176     public void cancelIntentSender(IIntentSender sender) {
7177         if (!(sender instanceof PendingIntentRecord)) {
7178             return;
7179         }
7180         synchronized(this) {
7181             PendingIntentRecord rec = (PendingIntentRecord)sender;
7182             try {
7183                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7184                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7185                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7186                     String msg = "Permission Denial: cancelIntentSender() from pid="
7187                         + Binder.getCallingPid()
7188                         + ", uid=" + Binder.getCallingUid()
7189                         + " is not allowed to cancel packges "
7190                         + rec.key.packageName;
7191                     Slog.w(TAG, msg);
7192                     throw new SecurityException(msg);
7193                 }
7194             } catch (RemoteException e) {
7195                 throw new SecurityException(e);
7196             }
7197             cancelIntentSenderLocked(rec, true);
7198         }
7199     }
7200
7201     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7202         rec.canceled = true;
7203         mIntentSenderRecords.remove(rec.key);
7204         if (cleanActivity && rec.key.activity != null) {
7205             rec.key.activity.pendingResults.remove(rec.ref);
7206         }
7207     }
7208
7209     @Override
7210     public String getPackageForIntentSender(IIntentSender pendingResult) {
7211         if (!(pendingResult instanceof PendingIntentRecord)) {
7212             return null;
7213         }
7214         try {
7215             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7216             return res.key.packageName;
7217         } catch (ClassCastException e) {
7218         }
7219         return null;
7220     }
7221
7222     @Override
7223     public int getUidForIntentSender(IIntentSender sender) {
7224         if (sender instanceof PendingIntentRecord) {
7225             try {
7226                 PendingIntentRecord res = (PendingIntentRecord)sender;
7227                 return res.uid;
7228             } catch (ClassCastException e) {
7229             }
7230         }
7231         return -1;
7232     }
7233
7234     @Override
7235     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7236         if (!(pendingResult instanceof PendingIntentRecord)) {
7237             return false;
7238         }
7239         try {
7240             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7241             if (res.key.allIntents == null) {
7242                 return false;
7243             }
7244             for (int i=0; i<res.key.allIntents.length; i++) {
7245                 Intent intent = res.key.allIntents[i];
7246                 if (intent.getPackage() != null && intent.getComponent() != null) {
7247                     return false;
7248                 }
7249             }
7250             return true;
7251         } catch (ClassCastException e) {
7252         }
7253         return false;
7254     }
7255
7256     @Override
7257     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7258         if (!(pendingResult instanceof PendingIntentRecord)) {
7259             return false;
7260         }
7261         try {
7262             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7263             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7264                 return true;
7265             }
7266             return false;
7267         } catch (ClassCastException e) {
7268         }
7269         return false;
7270     }
7271
7272     @Override
7273     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7274         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7275                 "getIntentForIntentSender()");
7276         if (!(pendingResult instanceof PendingIntentRecord)) {
7277             return null;
7278         }
7279         try {
7280             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7281             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7282         } catch (ClassCastException e) {
7283         }
7284         return null;
7285     }
7286
7287     @Override
7288     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7289         if (!(pendingResult instanceof PendingIntentRecord)) {
7290             return null;
7291         }
7292         try {
7293             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7294             synchronized (this) {
7295                 return getTagForIntentSenderLocked(res, prefix);
7296             }
7297         } catch (ClassCastException e) {
7298         }
7299         return null;
7300     }
7301
7302     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7303         final Intent intent = res.key.requestIntent;
7304         if (intent != null) {
7305             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7306                     || res.lastTagPrefix.equals(prefix))) {
7307                 return res.lastTag;
7308             }
7309             res.lastTagPrefix = prefix;
7310             final StringBuilder sb = new StringBuilder(128);
7311             if (prefix != null) {
7312                 sb.append(prefix);
7313             }
7314             if (intent.getAction() != null) {
7315                 sb.append(intent.getAction());
7316             } else if (intent.getComponent() != null) {
7317                 intent.getComponent().appendShortString(sb);
7318             } else {
7319                 sb.append("?");
7320             }
7321             return res.lastTag = sb.toString();
7322         }
7323         return null;
7324     }
7325
7326     @Override
7327     public void setProcessLimit(int max) {
7328         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329                 "setProcessLimit()");
7330         synchronized (this) {
7331             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7332             mProcessLimitOverride = max;
7333         }
7334         trimApplications();
7335     }
7336
7337     @Override
7338     public int getProcessLimit() {
7339         synchronized (this) {
7340             return mProcessLimitOverride;
7341         }
7342     }
7343
7344     void foregroundTokenDied(ForegroundToken token) {
7345         synchronized (ActivityManagerService.this) {
7346             synchronized (mPidsSelfLocked) {
7347                 ForegroundToken cur
7348                     = mForegroundProcesses.get(token.pid);
7349                 if (cur != token) {
7350                     return;
7351                 }
7352                 mForegroundProcesses.remove(token.pid);
7353                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7354                 if (pr == null) {
7355                     return;
7356                 }
7357                 pr.forcingToForeground = null;
7358                 updateProcessForegroundLocked(pr, false, false);
7359             }
7360             updateOomAdjLocked();
7361         }
7362     }
7363
7364     @Override
7365     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7366         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7367                 "setProcessForeground()");
7368         synchronized(this) {
7369             boolean changed = false;
7370
7371             synchronized (mPidsSelfLocked) {
7372                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7373                 if (pr == null && isForeground) {
7374                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7375                     return;
7376                 }
7377                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7378                 if (oldToken != null) {
7379                     oldToken.token.unlinkToDeath(oldToken, 0);
7380                     mForegroundProcesses.remove(pid);
7381                     if (pr != null) {
7382                         pr.forcingToForeground = null;
7383                     }
7384                     changed = true;
7385                 }
7386                 if (isForeground && token != null) {
7387                     ForegroundToken newToken = new ForegroundToken() {
7388                         @Override
7389                         public void binderDied() {
7390                             foregroundTokenDied(this);
7391                         }
7392                     };
7393                     newToken.pid = pid;
7394                     newToken.token = token;
7395                     try {
7396                         token.linkToDeath(newToken, 0);
7397                         mForegroundProcesses.put(pid, newToken);
7398                         pr.forcingToForeground = token;
7399                         changed = true;
7400                     } catch (RemoteException e) {
7401                         // If the process died while doing this, we will later
7402                         // do the cleanup with the process death link.
7403                     }
7404                 }
7405             }
7406
7407             if (changed) {
7408                 updateOomAdjLocked();
7409             }
7410         }
7411     }
7412
7413     @Override
7414     public boolean isAppForeground(int uid) throws RemoteException {
7415         synchronized (this) {
7416             UidRecord uidRec = mActiveUids.get(uid);
7417             if (uidRec == null || uidRec.idle) {
7418                 return false;
7419             }
7420             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7421         }
7422     }
7423
7424     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7425     // be guarded by permission checking.
7426     int getUidState(int uid) {
7427         synchronized (this) {
7428             UidRecord uidRec = mActiveUids.get(uid);
7429             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7430         }
7431     }
7432
7433     @Override
7434     public boolean isInMultiWindowMode(IBinder token) {
7435         final long origId = Binder.clearCallingIdentity();
7436         try {
7437             synchronized(this) {
7438                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7439                 if (r == null) {
7440                     return false;
7441                 }
7442                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7443                 return !r.task.mFullscreen;
7444             }
7445         } finally {
7446             Binder.restoreCallingIdentity(origId);
7447         }
7448     }
7449
7450     @Override
7451     public boolean isInPictureInPictureMode(IBinder token) {
7452         final long origId = Binder.clearCallingIdentity();
7453         try {
7454             synchronized(this) {
7455                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7456                 if (stack == null) {
7457                     return false;
7458                 }
7459                 return stack.mStackId == PINNED_STACK_ID;
7460             }
7461         } finally {
7462             Binder.restoreCallingIdentity(origId);
7463         }
7464     }
7465
7466     @Override
7467     public void enterPictureInPictureMode(IBinder token) {
7468         final long origId = Binder.clearCallingIdentity();
7469         try {
7470             synchronized(this) {
7471                 if (!mSupportsPictureInPicture) {
7472                     throw new IllegalStateException("enterPictureInPictureMode: "
7473                             + "Device doesn't support picture-in-picture mode.");
7474                 }
7475
7476                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7477
7478                 if (r == null) {
7479                     throw new IllegalStateException("enterPictureInPictureMode: "
7480                             + "Can't find activity for token=" + token);
7481                 }
7482
7483                 if (!r.supportsPictureInPicture()) {
7484                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7485                             + "Picture-In-Picture not supported for r=" + r);
7486                 }
7487
7488                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7489                 // current bounds.
7490                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7491                 final Rect bounds = (pinnedStack != null)
7492                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7493
7494                 mStackSupervisor.moveActivityToPinnedStackLocked(
7495                         r, "enterPictureInPictureMode", bounds);
7496             }
7497         } finally {
7498             Binder.restoreCallingIdentity(origId);
7499         }
7500     }
7501
7502     // =========================================================
7503     // PROCESS INFO
7504     // =========================================================
7505
7506     static class ProcessInfoService extends IProcessInfoService.Stub {
7507         final ActivityManagerService mActivityManagerService;
7508         ProcessInfoService(ActivityManagerService activityManagerService) {
7509             mActivityManagerService = activityManagerService;
7510         }
7511
7512         @Override
7513         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7514             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7515                     /*in*/ pids, /*out*/ states, null);
7516         }
7517
7518         @Override
7519         public void getProcessStatesAndOomScoresFromPids(
7520                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7521             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7522                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7523         }
7524     }
7525
7526     /**
7527      * For each PID in the given input array, write the current process state
7528      * for that process into the states array, or -1 to indicate that no
7529      * process with the given PID exists. If scores array is provided, write
7530      * the oom score for the process into the scores array, with INVALID_ADJ
7531      * indicating the PID doesn't exist.
7532      */
7533     public void getProcessStatesAndOomScoresForPIDs(
7534             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7535         if (scores != null) {
7536             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7537                     "getProcessStatesAndOomScoresForPIDs()");
7538         }
7539
7540         if (pids == null) {
7541             throw new NullPointerException("pids");
7542         } else if (states == null) {
7543             throw new NullPointerException("states");
7544         } else if (pids.length != states.length) {
7545             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7546         } else if (scores != null && pids.length != scores.length) {
7547             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7548         }
7549
7550         synchronized (mPidsSelfLocked) {
7551             for (int i = 0; i < pids.length; i++) {
7552                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7553                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7554                         pr.curProcState;
7555                 if (scores != null) {
7556                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7557                 }
7558             }
7559         }
7560     }
7561
7562     // =========================================================
7563     // PERMISSIONS
7564     // =========================================================
7565
7566     static class PermissionController extends IPermissionController.Stub {
7567         ActivityManagerService mActivityManagerService;
7568         PermissionController(ActivityManagerService activityManagerService) {
7569             mActivityManagerService = activityManagerService;
7570         }
7571
7572         @Override
7573         public boolean checkPermission(String permission, int pid, int uid) {
7574             return mActivityManagerService.checkPermission(permission, pid,
7575                     uid) == PackageManager.PERMISSION_GRANTED;
7576         }
7577
7578         @Override
7579         public String[] getPackagesForUid(int uid) {
7580             return mActivityManagerService.mContext.getPackageManager()
7581                     .getPackagesForUid(uid);
7582         }
7583
7584         @Override
7585         public boolean isRuntimePermission(String permission) {
7586             try {
7587                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7588                         .getPermissionInfo(permission, 0);
7589                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7590             } catch (NameNotFoundException nnfe) {
7591                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7592             }
7593             return false;
7594         }
7595     }
7596
7597     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7598         @Override
7599         public int checkComponentPermission(String permission, int pid, int uid,
7600                 int owningUid, boolean exported) {
7601             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7602                     owningUid, exported);
7603         }
7604
7605         @Override
7606         public Object getAMSLock() {
7607             return ActivityManagerService.this;
7608         }
7609     }
7610
7611     /**
7612      * This can be called with or without the global lock held.
7613      */
7614     int checkComponentPermission(String permission, int pid, int uid,
7615             int owningUid, boolean exported) {
7616         if (pid == MY_PID) {
7617             return PackageManager.PERMISSION_GRANTED;
7618         }
7619         return ActivityManager.checkComponentPermission(permission, uid,
7620                 owningUid, exported);
7621     }
7622
7623     /**
7624      * As the only public entry point for permissions checking, this method
7625      * can enforce the semantic that requesting a check on a null global
7626      * permission is automatically denied.  (Internally a null permission
7627      * string is used when calling {@link #checkComponentPermission} in cases
7628      * when only uid-based security is needed.)
7629      *
7630      * This can be called with or without the global lock held.
7631      */
7632     @Override
7633     public int checkPermission(String permission, int pid, int uid) {
7634         if (permission == null) {
7635             return PackageManager.PERMISSION_DENIED;
7636         }
7637         return checkComponentPermission(permission, pid, uid, -1, true);
7638     }
7639
7640     @Override
7641     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7642         if (permission == null) {
7643             return PackageManager.PERMISSION_DENIED;
7644         }
7645
7646         // We might be performing an operation on behalf of an indirect binder
7647         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7648         // client identity accordingly before proceeding.
7649         Identity tlsIdentity = sCallerIdentity.get();
7650         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7651             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7652                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7653             uid = tlsIdentity.uid;
7654             pid = tlsIdentity.pid;
7655         }
7656
7657         return checkComponentPermission(permission, pid, uid, -1, true);
7658     }
7659
7660     /**
7661      * Binder IPC calls go through the public entry point.
7662      * This can be called with or without the global lock held.
7663      */
7664     int checkCallingPermission(String permission) {
7665         return checkPermission(permission,
7666                 Binder.getCallingPid(),
7667                 UserHandle.getAppId(Binder.getCallingUid()));
7668     }
7669
7670     /**
7671      * This can be called with or without the global lock held.
7672      */
7673     void enforceCallingPermission(String permission, String func) {
7674         if (checkCallingPermission(permission)
7675                 == PackageManager.PERMISSION_GRANTED) {
7676             return;
7677         }
7678
7679         String msg = "Permission Denial: " + func + " from pid="
7680                 + Binder.getCallingPid()
7681                 + ", uid=" + Binder.getCallingUid()
7682                 + " requires " + permission;
7683         Slog.w(TAG, msg);
7684         throw new SecurityException(msg);
7685     }
7686
7687     /**
7688      * Determine if UID is holding permissions required to access {@link Uri} in
7689      * the given {@link ProviderInfo}. Final permission checking is always done
7690      * in {@link ContentProvider}.
7691      */
7692     private final boolean checkHoldingPermissionsLocked(
7693             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7694         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7695                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7696         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7697             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7698                     != PERMISSION_GRANTED) {
7699                 return false;
7700             }
7701         }
7702         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7703     }
7704
7705     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7706             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7707         if (pi.applicationInfo.uid == uid) {
7708             return true;
7709         } else if (!pi.exported) {
7710             return false;
7711         }
7712
7713         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7714         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7715         try {
7716             // check if target holds top-level <provider> permissions
7717             if (!readMet && pi.readPermission != null && considerUidPermissions
7718                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7719                 readMet = true;
7720             }
7721             if (!writeMet && pi.writePermission != null && considerUidPermissions
7722                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7723                 writeMet = true;
7724             }
7725
7726             // track if unprotected read/write is allowed; any denied
7727             // <path-permission> below removes this ability
7728             boolean allowDefaultRead = pi.readPermission == null;
7729             boolean allowDefaultWrite = pi.writePermission == null;
7730
7731             // check if target holds any <path-permission> that match uri
7732             final PathPermission[] pps = pi.pathPermissions;
7733             if (pps != null) {
7734                 final String path = grantUri.uri.getPath();
7735                 int i = pps.length;
7736                 while (i > 0 && (!readMet || !writeMet)) {
7737                     i--;
7738                     PathPermission pp = pps[i];
7739                     if (pp.match(path)) {
7740                         if (!readMet) {
7741                             final String pprperm = pp.getReadPermission();
7742                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7743                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7744                                     + ": match=" + pp.match(path)
7745                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7746                             if (pprperm != null) {
7747                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7748                                         == PERMISSION_GRANTED) {
7749                                     readMet = true;
7750                                 } else {
7751                                     allowDefaultRead = false;
7752                                 }
7753                             }
7754                         }
7755                         if (!writeMet) {
7756                             final String ppwperm = pp.getWritePermission();
7757                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7759                                     + ": match=" + pp.match(path)
7760                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7761                             if (ppwperm != null) {
7762                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7763                                         == PERMISSION_GRANTED) {
7764                                     writeMet = true;
7765                                 } else {
7766                                     allowDefaultWrite = false;
7767                                 }
7768                             }
7769                         }
7770                     }
7771                 }
7772             }
7773
7774             // grant unprotected <provider> read/write, if not blocked by
7775             // <path-permission> above
7776             if (allowDefaultRead) readMet = true;
7777             if (allowDefaultWrite) writeMet = true;
7778
7779         } catch (RemoteException e) {
7780             return false;
7781         }
7782
7783         return readMet && writeMet;
7784     }
7785
7786     public int getAppStartMode(int uid, String packageName) {
7787         synchronized (this) {
7788             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7789         }
7790     }
7791
7792     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7793             boolean allowWhenForeground) {
7794         UidRecord uidRec = mActiveUids.get(uid);
7795         if (!mLenientBackgroundCheck) {
7796             if (!allowWhenForeground || uidRec == null
7797                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7798                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7799                         packageName) != AppOpsManager.MODE_ALLOWED) {
7800                     return ActivityManager.APP_START_MODE_DELAYED;
7801                 }
7802             }
7803
7804         } else if (uidRec == null || uidRec.idle) {
7805             if (callingPid >= 0) {
7806                 ProcessRecord proc;
7807                 synchronized (mPidsSelfLocked) {
7808                     proc = mPidsSelfLocked.get(callingPid);
7809                 }
7810                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7811                     // Whoever is instigating this is in the foreground, so we will allow it
7812                     // to go through.
7813                     return ActivityManager.APP_START_MODE_NORMAL;
7814                 }
7815             }
7816             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7817                     != AppOpsManager.MODE_ALLOWED) {
7818                 return ActivityManager.APP_START_MODE_DELAYED;
7819             }
7820         }
7821         return ActivityManager.APP_START_MODE_NORMAL;
7822     }
7823
7824     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7825         ProviderInfo pi = null;
7826         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7827         if (cpr != null) {
7828             pi = cpr.info;
7829         } else {
7830             try {
7831                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7832                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7833             } catch (RemoteException ex) {
7834             }
7835         }
7836         return pi;
7837     }
7838
7839     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7840         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7841         if (targetUris != null) {
7842             return targetUris.get(grantUri);
7843         }
7844         return null;
7845     }
7846
7847     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7848             String targetPkg, int targetUid, GrantUri grantUri) {
7849         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7850         if (targetUris == null) {
7851             targetUris = Maps.newArrayMap();
7852             mGrantedUriPermissions.put(targetUid, targetUris);
7853         }
7854
7855         UriPermission perm = targetUris.get(grantUri);
7856         if (perm == null) {
7857             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7858             targetUris.put(grantUri, perm);
7859         }
7860
7861         return perm;
7862     }
7863
7864     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7865             final int modeFlags) {
7866         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7867         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7868                 : UriPermission.STRENGTH_OWNED;
7869
7870         // Root gets to do everything.
7871         if (uid == 0) {
7872             return true;
7873         }
7874
7875         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7876         if (perms == null) return false;
7877
7878         // First look for exact match
7879         final UriPermission exactPerm = perms.get(grantUri);
7880         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7881             return true;
7882         }
7883
7884         // No exact match, look for prefixes
7885         final int N = perms.size();
7886         for (int i = 0; i < N; i++) {
7887             final UriPermission perm = perms.valueAt(i);
7888             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7889                     && perm.getStrength(modeFlags) >= minStrength) {
7890                 return true;
7891             }
7892         }
7893
7894         return false;
7895     }
7896
7897     /**
7898      * @param uri This uri must NOT contain an embedded userId.
7899      * @param userId The userId in which the uri is to be resolved.
7900      */
7901     @Override
7902     public int checkUriPermission(Uri uri, int pid, int uid,
7903             final int modeFlags, int userId, IBinder callerToken) {
7904         enforceNotIsolatedCaller("checkUriPermission");
7905
7906         // Another redirected-binder-call permissions check as in
7907         // {@link checkPermissionWithToken}.
7908         Identity tlsIdentity = sCallerIdentity.get();
7909         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7910             uid = tlsIdentity.uid;
7911             pid = tlsIdentity.pid;
7912         }
7913
7914         // Our own process gets to do everything.
7915         if (pid == MY_PID) {
7916             return PackageManager.PERMISSION_GRANTED;
7917         }
7918         synchronized (this) {
7919             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7920                     ? PackageManager.PERMISSION_GRANTED
7921                     : PackageManager.PERMISSION_DENIED;
7922         }
7923     }
7924
7925     /**
7926      * Check if the targetPkg can be granted permission to access uri by
7927      * the callingUid using the given modeFlags.  Throws a security exception
7928      * if callingUid is not allowed to do this.  Returns the uid of the target
7929      * if the URI permission grant should be performed; returns -1 if it is not
7930      * needed (for example targetPkg already has permission to access the URI).
7931      * If you already know the uid of the target, you can supply it in
7932      * lastTargetUid else set that to -1.
7933      */
7934     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7935             final int modeFlags, int lastTargetUid) {
7936         if (!Intent.isAccessUriMode(modeFlags)) {
7937             return -1;
7938         }
7939
7940         if (targetPkg != null) {
7941             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7942                     "Checking grant " + targetPkg + " permission to " + grantUri);
7943         }
7944
7945         final IPackageManager pm = AppGlobals.getPackageManager();
7946
7947         // If this is not a content: uri, we can't do anything with it.
7948         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7949             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                     "Can't grant URI permission for non-content URI: " + grantUri);
7951             return -1;
7952         }
7953
7954         final String authority = grantUri.uri.getAuthority();
7955         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7956         if (pi == null) {
7957             Slog.w(TAG, "No content provider found for permission check: " +
7958                     grantUri.uri.toSafeString());
7959             return -1;
7960         }
7961
7962         int targetUid = lastTargetUid;
7963         if (targetUid < 0 && targetPkg != null) {
7964             try {
7965                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7966                         UserHandle.getUserId(callingUid));
7967                 if (targetUid < 0) {
7968                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7969                             "Can't grant URI permission no uid for: " + targetPkg);
7970                     return -1;
7971                 }
7972             } catch (RemoteException ex) {
7973                 return -1;
7974             }
7975         }
7976
7977         if (targetUid >= 0) {
7978             // First...  does the target actually need this permission?
7979             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7980                 // No need to grant the target this permission.
7981                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                         "Target " + targetPkg + " already has full permission to " + grantUri);
7983                 return -1;
7984             }
7985         } else {
7986             // First...  there is no target package, so can anyone access it?
7987             boolean allowed = pi.exported;
7988             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7989                 if (pi.readPermission != null) {
7990                     allowed = false;
7991                 }
7992             }
7993             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7994                 if (pi.writePermission != null) {
7995                     allowed = false;
7996                 }
7997             }
7998             if (allowed) {
7999                 return -1;
8000             }
8001         }
8002
8003         /* There is a special cross user grant if:
8004          * - The target is on another user.
8005          * - Apps on the current user can access the uri without any uid permissions.
8006          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8007          * grant uri permissions.
8008          */
8009         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8010                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8011                 modeFlags, false /*without considering the uid permissions*/);
8012
8013         // Second...  is the provider allowing granting of URI permissions?
8014         if (!specialCrossUserGrant) {
8015             if (!pi.grantUriPermissions) {
8016                 throw new SecurityException("Provider " + pi.packageName
8017                         + "/" + pi.name
8018                         + " does not allow granting of Uri permissions (uri "
8019                         + grantUri + ")");
8020             }
8021             if (pi.uriPermissionPatterns != null) {
8022                 final int N = pi.uriPermissionPatterns.length;
8023                 boolean allowed = false;
8024                 for (int i=0; i<N; i++) {
8025                     if (pi.uriPermissionPatterns[i] != null
8026                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8027                         allowed = true;
8028                         break;
8029                     }
8030                 }
8031                 if (!allowed) {
8032                     throw new SecurityException("Provider " + pi.packageName
8033                             + "/" + pi.name
8034                             + " does not allow granting of permission to path of Uri "
8035                             + grantUri);
8036                 }
8037             }
8038         }
8039
8040         // Third...  does the caller itself have permission to access
8041         // this uri?
8042         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8043             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8044                 // Require they hold a strong enough Uri permission
8045                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8046                     throw new SecurityException("Uid " + callingUid
8047                             + " does not have permission to uri " + grantUri);
8048                 }
8049             }
8050         }
8051         return targetUid;
8052     }
8053
8054     /**
8055      * @param uri This uri must NOT contain an embedded userId.
8056      * @param userId The userId in which the uri is to be resolved.
8057      */
8058     @Override
8059     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8060             final int modeFlags, int userId) {
8061         enforceNotIsolatedCaller("checkGrantUriPermission");
8062         synchronized(this) {
8063             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8064                     new GrantUri(userId, uri, false), modeFlags, -1);
8065         }
8066     }
8067
8068     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8069             final int modeFlags, UriPermissionOwner owner) {
8070         if (!Intent.isAccessUriMode(modeFlags)) {
8071             return;
8072         }
8073
8074         // So here we are: the caller has the assumed permission
8075         // to the uri, and the target doesn't.  Let's now give this to
8076         // the target.
8077
8078         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8080
8081         final String authority = grantUri.uri.getAuthority();
8082         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8083         if (pi == null) {
8084             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8085             return;
8086         }
8087
8088         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8089             grantUri.prefix = true;
8090         }
8091         final UriPermission perm = findOrCreateUriPermissionLocked(
8092                 pi.packageName, targetPkg, targetUid, grantUri);
8093         perm.grantModes(modeFlags, owner);
8094     }
8095
8096     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8097             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8098         if (targetPkg == null) {
8099             throw new NullPointerException("targetPkg");
8100         }
8101         int targetUid;
8102         final IPackageManager pm = AppGlobals.getPackageManager();
8103         try {
8104             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8105         } catch (RemoteException ex) {
8106             return;
8107         }
8108
8109         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8110                 targetUid);
8111         if (targetUid < 0) {
8112             return;
8113         }
8114
8115         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8116                 owner);
8117     }
8118
8119     static class NeededUriGrants extends ArrayList<GrantUri> {
8120         final String targetPkg;
8121         final int targetUid;
8122         final int flags;
8123
8124         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8125             this.targetPkg = targetPkg;
8126             this.targetUid = targetUid;
8127             this.flags = flags;
8128         }
8129     }
8130
8131     /**
8132      * Like checkGrantUriPermissionLocked, but takes an Intent.
8133      */
8134     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8135             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8136         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8138                 + " clip=" + (intent != null ? intent.getClipData() : null)
8139                 + " from " + intent + "; flags=0x"
8140                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8141
8142         if (targetPkg == null) {
8143             throw new NullPointerException("targetPkg");
8144         }
8145
8146         if (intent == null) {
8147             return null;
8148         }
8149         Uri data = intent.getData();
8150         ClipData clip = intent.getClipData();
8151         if (data == null && clip == null) {
8152             return null;
8153         }
8154         // Default userId for uris in the intent (if they don't specify it themselves)
8155         int contentUserHint = intent.getContentUserHint();
8156         if (contentUserHint == UserHandle.USER_CURRENT) {
8157             contentUserHint = UserHandle.getUserId(callingUid);
8158         }
8159         final IPackageManager pm = AppGlobals.getPackageManager();
8160         int targetUid;
8161         if (needed != null) {
8162             targetUid = needed.targetUid;
8163         } else {
8164             try {
8165                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8166                         targetUserId);
8167             } catch (RemoteException ex) {
8168                 return null;
8169             }
8170             if (targetUid < 0) {
8171                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                         "Can't grant URI permission no uid for: " + targetPkg
8173                         + " on user " + targetUserId);
8174                 return null;
8175             }
8176         }
8177         if (data != null) {
8178             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8179             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8180                     targetUid);
8181             if (targetUid > 0) {
8182                 if (needed == null) {
8183                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8184                 }
8185                 needed.add(grantUri);
8186             }
8187         }
8188         if (clip != null) {
8189             for (int i=0; i<clip.getItemCount(); i++) {
8190                 Uri uri = clip.getItemAt(i).getUri();
8191                 if (uri != null) {
8192                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8193                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8194                             targetUid);
8195                     if (targetUid > 0) {
8196                         if (needed == null) {
8197                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8198                         }
8199                         needed.add(grantUri);
8200                     }
8201                 } else {
8202                     Intent clipIntent = clip.getItemAt(i).getIntent();
8203                     if (clipIntent != null) {
8204                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8205                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8206                         if (newNeeded != null) {
8207                             needed = newNeeded;
8208                         }
8209                     }
8210                 }
8211             }
8212         }
8213
8214         return needed;
8215     }
8216
8217     /**
8218      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8219      */
8220     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8221             UriPermissionOwner owner) {
8222         if (needed != null) {
8223             for (int i=0; i<needed.size(); i++) {
8224                 GrantUri grantUri = needed.get(i);
8225                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8226                         grantUri, needed.flags, owner);
8227             }
8228         }
8229     }
8230
8231     void grantUriPermissionFromIntentLocked(int callingUid,
8232             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8233         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8234                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8235         if (needed == null) {
8236             return;
8237         }
8238
8239         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8240     }
8241
8242     /**
8243      * @param uri This uri must NOT contain an embedded userId.
8244      * @param userId The userId in which the uri is to be resolved.
8245      */
8246     @Override
8247     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8248             final int modeFlags, int userId) {
8249         enforceNotIsolatedCaller("grantUriPermission");
8250         GrantUri grantUri = new GrantUri(userId, uri, false);
8251         synchronized(this) {
8252             final ProcessRecord r = getRecordForAppLocked(caller);
8253             if (r == null) {
8254                 throw new SecurityException("Unable to find app for caller "
8255                         + caller
8256                         + " when granting permission to uri " + grantUri);
8257             }
8258             if (targetPkg == null) {
8259                 throw new IllegalArgumentException("null target");
8260             }
8261             if (grantUri == null) {
8262                 throw new IllegalArgumentException("null uri");
8263             }
8264
8265             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8266                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8267                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8268                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8269
8270             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8271                     UserHandle.getUserId(r.uid));
8272         }
8273     }
8274
8275     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8276         if (perm.modeFlags == 0) {
8277             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8278                     perm.targetUid);
8279             if (perms != null) {
8280                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8282
8283                 perms.remove(perm.uri);
8284                 if (perms.isEmpty()) {
8285                     mGrantedUriPermissions.remove(perm.targetUid);
8286                 }
8287             }
8288         }
8289     }
8290
8291     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8292         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293                 "Revoking all granted permissions to " + grantUri);
8294
8295         final IPackageManager pm = AppGlobals.getPackageManager();
8296         final String authority = grantUri.uri.getAuthority();
8297         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8298         if (pi == null) {
8299             Slog.w(TAG, "No content provider found for permission revoke: "
8300                     + grantUri.toSafeString());
8301             return;
8302         }
8303
8304         // Does the caller have this permission on the URI?
8305         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8306             // If they don't have direct access to the URI, then revoke any
8307             // ownerless URI permissions that have been granted to them.
8308             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8309             if (perms != null) {
8310                 boolean persistChanged = false;
8311                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8312                     final UriPermission perm = it.next();
8313                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8314                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8315                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316                                 "Revoking non-owned " + perm.targetUid
8317                                 + " permission to " + perm.uri);
8318                         persistChanged |= perm.revokeModes(
8319                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8320                         if (perm.modeFlags == 0) {
8321                             it.remove();
8322                         }
8323                     }
8324                 }
8325                 if (perms.isEmpty()) {
8326                     mGrantedUriPermissions.remove(callingUid);
8327                 }
8328                 if (persistChanged) {
8329                     schedulePersistUriGrants();
8330                 }
8331             }
8332             return;
8333         }
8334
8335         boolean persistChanged = false;
8336
8337         // Go through all of the permissions and remove any that match.
8338         int N = mGrantedUriPermissions.size();
8339         for (int i = 0; i < N; i++) {
8340             final int targetUid = mGrantedUriPermissions.keyAt(i);
8341             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8342
8343             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8344                 final UriPermission perm = it.next();
8345                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8346                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8347                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8349                     persistChanged |= perm.revokeModes(
8350                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8351                     if (perm.modeFlags == 0) {
8352                         it.remove();
8353                     }
8354                 }
8355             }
8356
8357             if (perms.isEmpty()) {
8358                 mGrantedUriPermissions.remove(targetUid);
8359                 N--;
8360                 i--;
8361             }
8362         }
8363
8364         if (persistChanged) {
8365             schedulePersistUriGrants();
8366         }
8367     }
8368
8369     /**
8370      * @param uri This uri must NOT contain an embedded userId.
8371      * @param userId The userId in which the uri is to be resolved.
8372      */
8373     @Override
8374     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8375             int userId) {
8376         enforceNotIsolatedCaller("revokeUriPermission");
8377         synchronized(this) {
8378             final ProcessRecord r = getRecordForAppLocked(caller);
8379             if (r == null) {
8380                 throw new SecurityException("Unable to find app for caller "
8381                         + caller
8382                         + " when revoking permission to uri " + uri);
8383             }
8384             if (uri == null) {
8385                 Slog.w(TAG, "revokeUriPermission: null uri");
8386                 return;
8387             }
8388
8389             if (!Intent.isAccessUriMode(modeFlags)) {
8390                 return;
8391             }
8392
8393             final String authority = uri.getAuthority();
8394             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8395             if (pi == null) {
8396                 Slog.w(TAG, "No content provider found for permission revoke: "
8397                         + uri.toSafeString());
8398                 return;
8399             }
8400
8401             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8402         }
8403     }
8404
8405     /**
8406      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8407      * given package.
8408      *
8409      * @param packageName Package name to match, or {@code null} to apply to all
8410      *            packages.
8411      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8412      *            to all users.
8413      * @param persistable If persistable grants should be removed.
8414      */
8415     private void removeUriPermissionsForPackageLocked(
8416             String packageName, int userHandle, boolean persistable) {
8417         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8418             throw new IllegalArgumentException("Must narrow by either package or user");
8419         }
8420
8421         boolean persistChanged = false;
8422
8423         int N = mGrantedUriPermissions.size();
8424         for (int i = 0; i < N; i++) {
8425             final int targetUid = mGrantedUriPermissions.keyAt(i);
8426             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8427
8428             // Only inspect grants matching user
8429             if (userHandle == UserHandle.USER_ALL
8430                     || userHandle == UserHandle.getUserId(targetUid)) {
8431                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8432                     final UriPermission perm = it.next();
8433
8434                     // Only inspect grants matching package
8435                     if (packageName == null || perm.sourcePkg.equals(packageName)
8436                             || perm.targetPkg.equals(packageName)) {
8437                         persistChanged |= perm.revokeModes(persistable
8438                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8439
8440                         // Only remove when no modes remain; any persisted grants
8441                         // will keep this alive.
8442                         if (perm.modeFlags == 0) {
8443                             it.remove();
8444                         }
8445                     }
8446                 }
8447
8448                 if (perms.isEmpty()) {
8449                     mGrantedUriPermissions.remove(targetUid);
8450                     N--;
8451                     i--;
8452                 }
8453             }
8454         }
8455
8456         if (persistChanged) {
8457             schedulePersistUriGrants();
8458         }
8459     }
8460
8461     @Override
8462     public IBinder newUriPermissionOwner(String name) {
8463         enforceNotIsolatedCaller("newUriPermissionOwner");
8464         synchronized(this) {
8465             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8466             return owner.getExternalTokenLocked();
8467         }
8468     }
8469
8470     @Override
8471     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8472         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8473         synchronized(this) {
8474             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8475             if (r == null) {
8476                 throw new IllegalArgumentException("Activity does not exist; token="
8477                         + activityToken);
8478             }
8479             return r.getUriPermissionsLocked().getExternalTokenLocked();
8480         }
8481     }
8482     /**
8483      * @param uri This uri must NOT contain an embedded userId.
8484      * @param sourceUserId The userId in which the uri is to be resolved.
8485      * @param targetUserId The userId of the app that receives the grant.
8486      */
8487     @Override
8488     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8489             final int modeFlags, int sourceUserId, int targetUserId) {
8490         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8491                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8492                 "grantUriPermissionFromOwner", null);
8493         synchronized(this) {
8494             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8495             if (owner == null) {
8496                 throw new IllegalArgumentException("Unknown owner: " + token);
8497             }
8498             if (fromUid != Binder.getCallingUid()) {
8499                 if (Binder.getCallingUid() != Process.myUid()) {
8500                     // Only system code can grant URI permissions on behalf
8501                     // of other users.
8502                     throw new SecurityException("nice try");
8503                 }
8504             }
8505             if (targetPkg == null) {
8506                 throw new IllegalArgumentException("null target");
8507             }
8508             if (uri == null) {
8509                 throw new IllegalArgumentException("null uri");
8510             }
8511
8512             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8513                     modeFlags, owner, targetUserId);
8514         }
8515     }
8516
8517     /**
8518      * @param uri This uri must NOT contain an embedded userId.
8519      * @param userId The userId in which the uri is to be resolved.
8520      */
8521     @Override
8522     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8523         synchronized(this) {
8524             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8525             if (owner == null) {
8526                 throw new IllegalArgumentException("Unknown owner: " + token);
8527             }
8528
8529             if (uri == null) {
8530                 owner.removeUriPermissionsLocked(mode);
8531             } else {
8532                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8533             }
8534         }
8535     }
8536
8537     private void schedulePersistUriGrants() {
8538         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8539             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8540                     10 * DateUtils.SECOND_IN_MILLIS);
8541         }
8542     }
8543
8544     private void writeGrantedUriPermissions() {
8545         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8546
8547         // Snapshot permissions so we can persist without lock
8548         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8549         synchronized (this) {
8550             final int size = mGrantedUriPermissions.size();
8551             for (int i = 0; i < size; i++) {
8552                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8553                 for (UriPermission perm : perms.values()) {
8554                     if (perm.persistedModeFlags != 0) {
8555                         persist.add(perm.snapshot());
8556                     }
8557                 }
8558             }
8559         }
8560
8561         FileOutputStream fos = null;
8562         try {
8563             fos = mGrantFile.startWrite();
8564
8565             XmlSerializer out = new FastXmlSerializer();
8566             out.setOutput(fos, StandardCharsets.UTF_8.name());
8567             out.startDocument(null, true);
8568             out.startTag(null, TAG_URI_GRANTS);
8569             for (UriPermission.Snapshot perm : persist) {
8570                 out.startTag(null, TAG_URI_GRANT);
8571                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8572                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8573                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8574                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8575                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8576                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8577                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8578                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8579                 out.endTag(null, TAG_URI_GRANT);
8580             }
8581             out.endTag(null, TAG_URI_GRANTS);
8582             out.endDocument();
8583
8584             mGrantFile.finishWrite(fos);
8585         } catch (IOException e) {
8586             if (fos != null) {
8587                 mGrantFile.failWrite(fos);
8588             }
8589         }
8590     }
8591
8592     private void readGrantedUriPermissionsLocked() {
8593         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8594
8595         final long now = System.currentTimeMillis();
8596
8597         FileInputStream fis = null;
8598         try {
8599             fis = mGrantFile.openRead();
8600             final XmlPullParser in = Xml.newPullParser();
8601             in.setInput(fis, StandardCharsets.UTF_8.name());
8602
8603             int type;
8604             while ((type = in.next()) != END_DOCUMENT) {
8605                 final String tag = in.getName();
8606                 if (type == START_TAG) {
8607                     if (TAG_URI_GRANT.equals(tag)) {
8608                         final int sourceUserId;
8609                         final int targetUserId;
8610                         final int userHandle = readIntAttribute(in,
8611                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8612                         if (userHandle != UserHandle.USER_NULL) {
8613                             // For backwards compatibility.
8614                             sourceUserId = userHandle;
8615                             targetUserId = userHandle;
8616                         } else {
8617                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8618                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8619                         }
8620                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8621                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8622                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8623                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8624                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8625                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8626
8627                         // Sanity check that provider still belongs to source package
8628                         final ProviderInfo pi = getProviderInfoLocked(
8629                                 uri.getAuthority(), sourceUserId);
8630                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8631                             int targetUid = -1;
8632                             try {
8633                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8634                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8635                             } catch (RemoteException e) {
8636                             }
8637                             if (targetUid != -1) {
8638                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8639                                         sourcePkg, targetPkg, targetUid,
8640                                         new GrantUri(sourceUserId, uri, prefix));
8641                                 perm.initPersistedModes(modeFlags, createdTime);
8642                             }
8643                         } else {
8644                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8645                                     + " but instead found " + pi);
8646                         }
8647                     }
8648                 }
8649             }
8650         } catch (FileNotFoundException e) {
8651             // Missing grants is okay
8652         } catch (IOException e) {
8653             Slog.wtf(TAG, "Failed reading Uri grants", e);
8654         } catch (XmlPullParserException e) {
8655             Slog.wtf(TAG, "Failed reading Uri grants", e);
8656         } finally {
8657             IoUtils.closeQuietly(fis);
8658         }
8659     }
8660
8661     /**
8662      * @param uri This uri must NOT contain an embedded userId.
8663      * @param userId The userId in which the uri is to be resolved.
8664      */
8665     @Override
8666     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8667         enforceNotIsolatedCaller("takePersistableUriPermission");
8668
8669         Preconditions.checkFlagsArgument(modeFlags,
8670                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8671
8672         synchronized (this) {
8673             final int callingUid = Binder.getCallingUid();
8674             boolean persistChanged = false;
8675             GrantUri grantUri = new GrantUri(userId, uri, false);
8676
8677             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8678                     new GrantUri(userId, uri, false));
8679             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8680                     new GrantUri(userId, uri, true));
8681
8682             final boolean exactValid = (exactPerm != null)
8683                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8684             final boolean prefixValid = (prefixPerm != null)
8685                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8686
8687             if (!(exactValid || prefixValid)) {
8688                 throw new SecurityException("No persistable permission grants found for UID "
8689                         + callingUid + " and Uri " + grantUri.toSafeString());
8690             }
8691
8692             if (exactValid) {
8693                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8694             }
8695             if (prefixValid) {
8696                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8697             }
8698
8699             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8700
8701             if (persistChanged) {
8702                 schedulePersistUriGrants();
8703             }
8704         }
8705     }
8706
8707     /**
8708      * @param uri This uri must NOT contain an embedded userId.
8709      * @param userId The userId in which the uri is to be resolved.
8710      */
8711     @Override
8712     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8713         enforceNotIsolatedCaller("releasePersistableUriPermission");
8714
8715         Preconditions.checkFlagsArgument(modeFlags,
8716                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8717
8718         synchronized (this) {
8719             final int callingUid = Binder.getCallingUid();
8720             boolean persistChanged = false;
8721
8722             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8723                     new GrantUri(userId, uri, false));
8724             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8725                     new GrantUri(userId, uri, true));
8726             if (exactPerm == null && prefixPerm == null) {
8727                 throw new SecurityException("No permission grants found for UID " + callingUid
8728                         + " and Uri " + uri.toSafeString());
8729             }
8730
8731             if (exactPerm != null) {
8732                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8733                 removeUriPermissionIfNeededLocked(exactPerm);
8734             }
8735             if (prefixPerm != null) {
8736                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8737                 removeUriPermissionIfNeededLocked(prefixPerm);
8738             }
8739
8740             if (persistChanged) {
8741                 schedulePersistUriGrants();
8742             }
8743         }
8744     }
8745
8746     /**
8747      * Prune any older {@link UriPermission} for the given UID until outstanding
8748      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8749      *
8750      * @return if any mutations occured that require persisting.
8751      */
8752     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8753         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8754         if (perms == null) return false;
8755         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8756
8757         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8758         for (UriPermission perm : perms.values()) {
8759             if (perm.persistedModeFlags != 0) {
8760                 persisted.add(perm);
8761             }
8762         }
8763
8764         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8765         if (trimCount <= 0) return false;
8766
8767         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8768         for (int i = 0; i < trimCount; i++) {
8769             final UriPermission perm = persisted.get(i);
8770
8771             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8772                     "Trimming grant created at " + perm.persistedCreateTime);
8773
8774             perm.releasePersistableModes(~0);
8775             removeUriPermissionIfNeededLocked(perm);
8776         }
8777
8778         return true;
8779     }
8780
8781     @Override
8782     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8783             String packageName, boolean incoming) {
8784         enforceNotIsolatedCaller("getPersistedUriPermissions");
8785         Preconditions.checkNotNull(packageName, "packageName");
8786
8787         final int callingUid = Binder.getCallingUid();
8788         final IPackageManager pm = AppGlobals.getPackageManager();
8789         try {
8790             final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8791                     UserHandle.getUserId(callingUid));
8792             if (packageUid != callingUid) {
8793                 throw new SecurityException(
8794                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8795             }
8796         } catch (RemoteException e) {
8797             throw new SecurityException("Failed to verify package name ownership");
8798         }
8799
8800         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8801         synchronized (this) {
8802             if (incoming) {
8803                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8804                         callingUid);
8805                 if (perms == null) {
8806                     Slog.w(TAG, "No permission grants found for " + packageName);
8807                 } else {
8808                     for (UriPermission perm : perms.values()) {
8809                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8810                             result.add(perm.buildPersistedPublicApiObject());
8811                         }
8812                     }
8813                 }
8814             } else {
8815                 final int size = mGrantedUriPermissions.size();
8816                 for (int i = 0; i < size; i++) {
8817                     final ArrayMap<GrantUri, UriPermission> perms =
8818                             mGrantedUriPermissions.valueAt(i);
8819                     for (UriPermission perm : perms.values()) {
8820                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8821                             result.add(perm.buildPersistedPublicApiObject());
8822                         }
8823                     }
8824                 }
8825             }
8826         }
8827         return new ParceledListSlice<android.content.UriPermission>(result);
8828     }
8829
8830     @Override
8831     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8832             String packageName, int userId) {
8833         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8834                 "getGrantedUriPermissions");
8835
8836         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8837         synchronized (this) {
8838             final int size = mGrantedUriPermissions.size();
8839             for (int i = 0; i < size; i++) {
8840                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8841                 for (UriPermission perm : perms.values()) {
8842                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8843                             && perm.persistedModeFlags != 0) {
8844                         result.add(perm.buildPersistedPublicApiObject());
8845                     }
8846                 }
8847             }
8848         }
8849         return new ParceledListSlice<android.content.UriPermission>(result);
8850     }
8851
8852     @Override
8853     public void clearGrantedUriPermissions(String packageName, int userId) {
8854         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8855                 "clearGrantedUriPermissions");
8856         removeUriPermissionsForPackageLocked(packageName, userId, true);
8857     }
8858
8859     @Override
8860     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8861         synchronized (this) {
8862             ProcessRecord app =
8863                 who != null ? getRecordForAppLocked(who) : null;
8864             if (app == null) return;
8865
8866             Message msg = Message.obtain();
8867             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8868             msg.obj = app;
8869             msg.arg1 = waiting ? 1 : 0;
8870             mUiHandler.sendMessage(msg);
8871         }
8872     }
8873
8874     @Override
8875     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8876         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8877         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8878         outInfo.availMem = Process.getFreeMemory();
8879         outInfo.totalMem = Process.getTotalMemory();
8880         outInfo.threshold = homeAppMem;
8881         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8882         outInfo.hiddenAppThreshold = cachedAppMem;
8883         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8884                 ProcessList.SERVICE_ADJ);
8885         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8886                 ProcessList.VISIBLE_APP_ADJ);
8887         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8888                 ProcessList.FOREGROUND_APP_ADJ);
8889     }
8890
8891     // =========================================================
8892     // TASK MANAGEMENT
8893     // =========================================================
8894
8895     @Override
8896     public List<IAppTask> getAppTasks(String callingPackage) {
8897         int callingUid = Binder.getCallingUid();
8898         long ident = Binder.clearCallingIdentity();
8899
8900         synchronized(this) {
8901             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8902             try {
8903                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8904
8905                 final int N = mRecentTasks.size();
8906                 for (int i = 0; i < N; i++) {
8907                     TaskRecord tr = mRecentTasks.get(i);
8908                     // Skip tasks that do not match the caller.  We don't need to verify
8909                     // callingPackage, because we are also limiting to callingUid and know
8910                     // that will limit to the correct security sandbox.
8911                     if (tr.effectiveUid != callingUid) {
8912                         continue;
8913                     }
8914                     Intent intent = tr.getBaseIntent();
8915                     if (intent == null ||
8916                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8917                         continue;
8918                     }
8919                     ActivityManager.RecentTaskInfo taskInfo =
8920                             createRecentTaskInfoFromTaskRecord(tr);
8921                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8922                     list.add(taskImpl);
8923                 }
8924             } finally {
8925                 Binder.restoreCallingIdentity(ident);
8926             }
8927             return list;
8928         }
8929     }
8930
8931     @Override
8932     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8933         final int callingUid = Binder.getCallingUid();
8934         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8935
8936         synchronized(this) {
8937             if (DEBUG_ALL) Slog.v(
8938                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8939
8940             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8941                     callingUid);
8942
8943             // TODO: Improve with MRU list from all ActivityStacks.
8944             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8945         }
8946
8947         return list;
8948     }
8949
8950     /**
8951      * Creates a new RecentTaskInfo from a TaskRecord.
8952      */
8953     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8954         // Update the task description to reflect any changes in the task stack
8955         tr.updateTaskDescription();
8956
8957         // Compose the recent task info
8958         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8959         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8960         rti.persistentId = tr.taskId;
8961         rti.baseIntent = new Intent(tr.getBaseIntent());
8962         rti.origActivity = tr.origActivity;
8963         rti.realActivity = tr.realActivity;
8964         rti.description = tr.lastDescription;
8965         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8966         rti.userId = tr.userId;
8967         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8968         rti.firstActiveTime = tr.firstActiveTime;
8969         rti.lastActiveTime = tr.lastActiveTime;
8970         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8971         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8972         rti.numActivities = 0;
8973         if (tr.mBounds != null) {
8974             rti.bounds = new Rect(tr.mBounds);
8975         }
8976         rti.isDockable = tr.canGoInDockedStack();
8977         rti.resizeMode = tr.mResizeMode;
8978
8979         ActivityRecord base = null;
8980         ActivityRecord top = null;
8981         ActivityRecord tmp;
8982
8983         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8984             tmp = tr.mActivities.get(i);
8985             if (tmp.finishing) {
8986                 continue;
8987             }
8988             base = tmp;
8989             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8990                 top = base;
8991             }
8992             rti.numActivities++;
8993         }
8994
8995         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8996         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8997
8998         return rti;
8999     }
9000
9001     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9002         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9003                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9004         if (!allowed) {
9005             if (checkPermission(android.Manifest.permission.GET_TASKS,
9006                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9007                 // Temporary compatibility: some existing apps on the system image may
9008                 // still be requesting the old permission and not switched to the new
9009                 // one; if so, we'll still allow them full access.  This means we need
9010                 // to see if they are holding the old permission and are a system app.
9011                 try {
9012                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9013                         allowed = true;
9014                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9015                                 + " is using old GET_TASKS but privileged; allowing");
9016                     }
9017                 } catch (RemoteException e) {
9018                 }
9019             }
9020         }
9021         if (!allowed) {
9022             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9023                     + " does not hold REAL_GET_TASKS; limiting output");
9024         }
9025         return allowed;
9026     }
9027
9028     @Override
9029     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9030         final int callingUid = Binder.getCallingUid();
9031         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9032                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9033
9034         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9035         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9036         synchronized (this) {
9037             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9038                     callingUid);
9039             final boolean detailed = checkCallingPermission(
9040                     android.Manifest.permission.GET_DETAILED_TASKS)
9041                     == PackageManager.PERMISSION_GRANTED;
9042
9043             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9044                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9045                 return Collections.emptyList();
9046             }
9047             mRecentTasks.loadUserRecentsLocked(userId);
9048
9049             final int recentsCount = mRecentTasks.size();
9050             ArrayList<ActivityManager.RecentTaskInfo> res =
9051                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9052
9053             final Set<Integer> includedUsers;
9054             if (includeProfiles) {
9055                 includedUsers = mUserController.getProfileIds(userId);
9056             } else {
9057                 includedUsers = new HashSet<>();
9058             }
9059             includedUsers.add(Integer.valueOf(userId));
9060
9061             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9062                 TaskRecord tr = mRecentTasks.get(i);
9063                 // Only add calling user or related users recent tasks
9064                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9065                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9066                     continue;
9067                 }
9068
9069                 if (tr.realActivitySuspended) {
9070                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9071                     continue;
9072                 }
9073
9074                 // Return the entry if desired by the caller.  We always return
9075                 // the first entry, because callers always expect this to be the
9076                 // foreground app.  We may filter others if the caller has
9077                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9078                 // we should exclude the entry.
9079
9080                 if (i == 0
9081                         || withExcluded
9082                         || (tr.intent == null)
9083                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9084                                 == 0)) {
9085                     if (!allowed) {
9086                         // If the caller doesn't have the GET_TASKS permission, then only
9087                         // allow them to see a small subset of tasks -- their own and home.
9088                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9089                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9090                             continue;
9091                         }
9092                     }
9093                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9094                         if (tr.stack != null && tr.stack.isHomeStack()) {
9095                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9096                                     "Skipping, home stack task: " + tr);
9097                             continue;
9098                         }
9099                     }
9100                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9101                         final ActivityStack stack = tr.stack;
9102                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9103                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9104                                     "Skipping, top task in docked stack: " + tr);
9105                             continue;
9106                         }
9107                     }
9108                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9109                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9110                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9111                                     "Skipping, pinned stack task: " + tr);
9112                             continue;
9113                         }
9114                     }
9115                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9116                         // Don't include auto remove tasks that are finished or finishing.
9117                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9118                                 "Skipping, auto-remove without activity: " + tr);
9119                         continue;
9120                     }
9121                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9122                             && !tr.isAvailable) {
9123                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9124                                 "Skipping, unavail real act: " + tr);
9125                         continue;
9126                     }
9127
9128                     if (!tr.mUserSetupComplete) {
9129                         // Don't include task launched while user is not done setting-up.
9130                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9131                                 "Skipping, user setup not complete: " + tr);
9132                         continue;
9133                     }
9134
9135                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9136                     if (!detailed) {
9137                         rti.baseIntent.replaceExtras((Bundle)null);
9138                     }
9139
9140                     res.add(rti);
9141                     maxNum--;
9142                 }
9143             }
9144             return res;
9145         }
9146     }
9147
9148     @Override
9149     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9150         synchronized (this) {
9151             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9152                     "getTaskThumbnail()");
9153             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9154                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9155             if (tr != null) {
9156                 return tr.getTaskThumbnailLocked();
9157             }
9158         }
9159         return null;
9160     }
9161
9162     @Override
9163     public int addAppTask(IBinder activityToken, Intent intent,
9164             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9165         final int callingUid = Binder.getCallingUid();
9166         final long callingIdent = Binder.clearCallingIdentity();
9167
9168         try {
9169             synchronized (this) {
9170                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9171                 if (r == null) {
9172                     throw new IllegalArgumentException("Activity does not exist; token="
9173                             + activityToken);
9174                 }
9175                 ComponentName comp = intent.getComponent();
9176                 if (comp == null) {
9177                     throw new IllegalArgumentException("Intent " + intent
9178                             + " must specify explicit component");
9179                 }
9180                 if (thumbnail.getWidth() != mThumbnailWidth
9181                         || thumbnail.getHeight() != mThumbnailHeight) {
9182                     throw new IllegalArgumentException("Bad thumbnail size: got "
9183                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9184                             + mThumbnailWidth + "x" + mThumbnailHeight);
9185                 }
9186                 if (intent.getSelector() != null) {
9187                     intent.setSelector(null);
9188                 }
9189                 if (intent.getSourceBounds() != null) {
9190                     intent.setSourceBounds(null);
9191                 }
9192                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9193                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9194                         // The caller has added this as an auto-remove task...  that makes no
9195                         // sense, so turn off auto-remove.
9196                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9197                     }
9198                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9199                     // Must be a new task.
9200                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9201                 }
9202                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9203                     mLastAddedTaskActivity = null;
9204                 }
9205                 ActivityInfo ainfo = mLastAddedTaskActivity;
9206                 if (ainfo == null) {
9207                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9208                             comp, 0, UserHandle.getUserId(callingUid));
9209                     if (ainfo.applicationInfo.uid != callingUid) {
9210                         throw new SecurityException(
9211                                 "Can't add task for another application: target uid="
9212                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9213                     }
9214                 }
9215
9216                 // Use the full screen as the context for the task thumbnail
9217                 final Point displaySize = new Point();
9218                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9219                 r.task.stack.getDisplaySize(displaySize);
9220                 thumbnailInfo.taskWidth = displaySize.x;
9221                 thumbnailInfo.taskHeight = displaySize.y;
9222                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9223
9224                 TaskRecord task = new TaskRecord(this,
9225                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9226                         ainfo, intent, description, thumbnailInfo);
9227
9228                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9229                 if (trimIdx >= 0) {
9230                     // If this would have caused a trim, then we'll abort because that
9231                     // means it would be added at the end of the list but then just removed.
9232                     return INVALID_TASK_ID;
9233                 }
9234
9235                 final int N = mRecentTasks.size();
9236                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9237                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9238                     tr.removedFromRecents();
9239                 }
9240
9241                 task.inRecents = true;
9242                 mRecentTasks.add(task);
9243                 r.task.stack.addTask(task, false, "addAppTask");
9244
9245                 task.setLastThumbnailLocked(thumbnail);
9246                 task.freeLastThumbnail();
9247
9248                 return task.taskId;
9249             }
9250         } finally {
9251             Binder.restoreCallingIdentity(callingIdent);
9252         }
9253     }
9254
9255     @Override
9256     public Point getAppTaskThumbnailSize() {
9257         synchronized (this) {
9258             return new Point(mThumbnailWidth,  mThumbnailHeight);
9259         }
9260     }
9261
9262     @Override
9263     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9264         synchronized (this) {
9265             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9266             if (r != null) {
9267                 r.setTaskDescription(td);
9268                 r.task.updateTaskDescription();
9269             }
9270         }
9271     }
9272
9273     @Override
9274     public void setTaskResizeable(int taskId, int resizeableMode) {
9275         synchronized (this) {
9276             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9277                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9278             if (task == null) {
9279                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9280                 return;
9281             }
9282             if (task.mResizeMode != resizeableMode) {
9283                 task.mResizeMode = resizeableMode;
9284                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9285                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9286                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9287             }
9288         }
9289     }
9290
9291     @Override
9292     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9293         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9294         long ident = Binder.clearCallingIdentity();
9295         try {
9296             synchronized (this) {
9297                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9298                 if (task == null) {
9299                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9300                     return;
9301                 }
9302                 int stackId = task.stack.mStackId;
9303                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9304                 // in crop windows resize mode or if the task size is affected by the docked stack
9305                 // changing size. No need to update configuration.
9306                 if (bounds != null && task.inCropWindowsResizeMode()
9307                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9308                     mWindowManager.scrollTask(task.taskId, bounds);
9309                     return;
9310                 }
9311
9312                 // Place the task in the right stack if it isn't there already based on
9313                 // the requested bounds.
9314                 // The stack transition logic is:
9315                 // - a null bounds on a freeform task moves that task to fullscreen
9316                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9317                 //   that task to freeform
9318                 // - otherwise the task is not moved
9319                 if (!StackId.isTaskResizeAllowed(stackId)) {
9320                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9321                 }
9322                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9323                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9324                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9325                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9326                 }
9327                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9328                 if (stackId != task.stack.mStackId) {
9329                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9330                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9331                     preserveWindow = false;
9332                 }
9333
9334                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9335                         false /* deferResume */);
9336             }
9337         } finally {
9338             Binder.restoreCallingIdentity(ident);
9339         }
9340     }
9341
9342     @Override
9343     public Rect getTaskBounds(int taskId) {
9344         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9345         long ident = Binder.clearCallingIdentity();
9346         Rect rect = new Rect();
9347         try {
9348             synchronized (this) {
9349                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351                 if (task == null) {
9352                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9353                     return rect;
9354                 }
9355                 if (task.stack != null) {
9356                     // Return the bounds from window manager since it will be adjusted for various
9357                     // things like the presense of a docked stack for tasks that aren't resizeable.
9358                     mWindowManager.getTaskBounds(task.taskId, rect);
9359                 } else {
9360                     // Task isn't in window manager yet since it isn't associated with a stack.
9361                     // Return the persist value from activity manager
9362                     if (task.mBounds != null) {
9363                         rect.set(task.mBounds);
9364                     } else if (task.mLastNonFullscreenBounds != null) {
9365                         rect.set(task.mLastNonFullscreenBounds);
9366                     }
9367                 }
9368             }
9369         } finally {
9370             Binder.restoreCallingIdentity(ident);
9371         }
9372         return rect;
9373     }
9374
9375     @Override
9376     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9377         if (userId != UserHandle.getCallingUserId()) {
9378             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9379                     "getTaskDescriptionIcon");
9380         }
9381         final File passedIconFile = new File(filePath);
9382         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9383                 passedIconFile.getName());
9384         if (!legitIconFile.getPath().equals(filePath)
9385                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9386             throw new IllegalArgumentException("Bad file path: " + filePath
9387                     + " passed for userId " + userId);
9388         }
9389         return mRecentTasks.getTaskDescriptionIcon(filePath);
9390     }
9391
9392     @Override
9393     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9394             throws RemoteException {
9395         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9396                 opts.getCustomInPlaceResId() == 0) {
9397             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9398                     "with valid animation");
9399         }
9400         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9401         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9402                 opts.getCustomInPlaceResId());
9403         mWindowManager.executeAppTransition();
9404     }
9405
9406     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9407             boolean removeFromRecents) {
9408         if (removeFromRecents) {
9409             mRecentTasks.remove(tr);
9410             tr.removedFromRecents();
9411         }
9412         ComponentName component = tr.getBaseIntent().getComponent();
9413         if (component == null) {
9414             Slog.w(TAG, "No component for base intent of task: " + tr);
9415             return;
9416         }
9417
9418         // Find any running services associated with this app and stop if needed.
9419         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9420
9421         if (!killProcess) {
9422             return;
9423         }
9424
9425         // Determine if the process(es) for this task should be killed.
9426         final String pkg = component.getPackageName();
9427         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9428         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9429         for (int i = 0; i < pmap.size(); i++) {
9430
9431             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9432             for (int j = 0; j < uids.size(); j++) {
9433                 ProcessRecord proc = uids.valueAt(j);
9434                 if (proc.userId != tr.userId) {
9435                     // Don't kill process for a different user.
9436                     continue;
9437                 }
9438                 if (proc == mHomeProcess) {
9439                     // Don't kill the home process along with tasks from the same package.
9440                     continue;
9441                 }
9442                 if (!proc.pkgList.containsKey(pkg)) {
9443                     // Don't kill process that is not associated with this task.
9444                     continue;
9445                 }
9446
9447                 for (int k = 0; k < proc.activities.size(); k++) {
9448                     TaskRecord otherTask = proc.activities.get(k).task;
9449                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9450                         // Don't kill process(es) that has an activity in a different task that is
9451                         // also in recents.
9452                         return;
9453                     }
9454                 }
9455
9456                 if (proc.foregroundServices) {
9457                     // Don't kill process(es) with foreground service.
9458                     return;
9459                 }
9460
9461                 // Add process to kill list.
9462                 procsToKill.add(proc);
9463             }
9464         }
9465
9466         // Kill the running processes.
9467         for (int i = 0; i < procsToKill.size(); i++) {
9468             ProcessRecord pr = procsToKill.get(i);
9469             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9470                     && pr.curReceiver == null) {
9471                 pr.kill("remove task", true);
9472             } else {
9473                 // We delay killing processes that are not in the background or running a receiver.
9474                 pr.waitingToKill = "remove task";
9475             }
9476         }
9477     }
9478
9479     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9480         // Remove all tasks with activities in the specified package from the list of recent tasks
9481         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9482             TaskRecord tr = mRecentTasks.get(i);
9483             if (tr.userId != userId) continue;
9484
9485             ComponentName cn = tr.intent.getComponent();
9486             if (cn != null && cn.getPackageName().equals(packageName)) {
9487                 // If the package name matches, remove the task.
9488                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9489             }
9490         }
9491     }
9492
9493     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9494             int userId) {
9495
9496         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9497             TaskRecord tr = mRecentTasks.get(i);
9498             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9499                 continue;
9500             }
9501
9502             ComponentName cn = tr.intent.getComponent();
9503             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9504                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9505             if (sameComponent) {
9506                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9507             }
9508         }
9509     }
9510
9511     /**
9512      * Removes the task with the specified task id.
9513      *
9514      * @param taskId Identifier of the task to be removed.
9515      * @param killProcess Kill any process associated with the task if possible.
9516      * @param removeFromRecents Whether to also remove the task from recents.
9517      * @return Returns true if the given task was found and removed.
9518      */
9519     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9520             boolean removeFromRecents) {
9521         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9522                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9523         if (tr != null) {
9524             tr.removeTaskActivitiesLocked();
9525             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9526             if (tr.isPersistable) {
9527                 notifyTaskPersisterLocked(null, true);
9528             }
9529             return true;
9530         }
9531         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9532         return false;
9533     }
9534
9535     @Override
9536     public void removeStack(int stackId) {
9537         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9538         if (stackId == HOME_STACK_ID) {
9539             throw new IllegalArgumentException("Removing home stack is not allowed.");
9540         }
9541
9542         synchronized (this) {
9543             final long ident = Binder.clearCallingIdentity();
9544             try {
9545                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9546                 if (stack == null) {
9547                     return;
9548                 }
9549                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9550                 for (int i = tasks.size() - 1; i >= 0; i--) {
9551                     removeTaskByIdLocked(
9552                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9553                 }
9554             } finally {
9555                 Binder.restoreCallingIdentity(ident);
9556             }
9557         }
9558     }
9559
9560     @Override
9561     public boolean removeTask(int taskId) {
9562         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9563         synchronized (this) {
9564             final long ident = Binder.clearCallingIdentity();
9565             try {
9566                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9567             } finally {
9568                 Binder.restoreCallingIdentity(ident);
9569             }
9570         }
9571     }
9572
9573     /**
9574      * TODO: Add mController hook
9575      */
9576     @Override
9577     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9578         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9579
9580         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9581         synchronized(this) {
9582             moveTaskToFrontLocked(taskId, flags, bOptions);
9583         }
9584     }
9585
9586     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9587         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9588
9589         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9590                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9591             ActivityOptions.abort(options);
9592             return;
9593         }
9594         final long origId = Binder.clearCallingIdentity();
9595         try {
9596             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9597             if (task == null) {
9598                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9599                 return;
9600             }
9601             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9602                 mStackSupervisor.showLockTaskToast();
9603                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9604                 return;
9605             }
9606             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9607             if (prev != null && prev.isRecentsActivity()) {
9608                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9609             }
9610             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9611                     false /* forceNonResizable */);
9612         } finally {
9613             Binder.restoreCallingIdentity(origId);
9614         }
9615         ActivityOptions.abort(options);
9616     }
9617
9618     /**
9619      * Moves an activity, and all of the other activities within the same task, to the bottom
9620      * of the history stack.  The activity's order within the task is unchanged.
9621      *
9622      * @param token A reference to the activity we wish to move
9623      * @param nonRoot If false then this only works if the activity is the root
9624      *                of a task; if true it will work for any activity in a task.
9625      * @return Returns true if the move completed, false if not.
9626      */
9627     @Override
9628     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9629         enforceNotIsolatedCaller("moveActivityTaskToBack");
9630         synchronized(this) {
9631             final long origId = Binder.clearCallingIdentity();
9632             try {
9633                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9634                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9635                 if (task != null) {
9636                     if (mStackSupervisor.isLockedTask(task)) {
9637                         mStackSupervisor.showLockTaskToast();
9638                         return false;
9639                     }
9640                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9641                 }
9642             } finally {
9643                 Binder.restoreCallingIdentity(origId);
9644             }
9645         }
9646         return false;
9647     }
9648
9649     @Override
9650     public void moveTaskBackwards(int task) {
9651         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9652                 "moveTaskBackwards()");
9653
9654         synchronized(this) {
9655             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9656                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9657                 return;
9658             }
9659             final long origId = Binder.clearCallingIdentity();
9660             moveTaskBackwardsLocked(task);
9661             Binder.restoreCallingIdentity(origId);
9662         }
9663     }
9664
9665     private final void moveTaskBackwardsLocked(int task) {
9666         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9667     }
9668
9669     @Override
9670     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9671             IActivityContainerCallback callback) throws RemoteException {
9672         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9673         synchronized (this) {
9674             if (parentActivityToken == null) {
9675                 throw new IllegalArgumentException("parent token must not be null");
9676             }
9677             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9678             if (r == null) {
9679                 return null;
9680             }
9681             if (callback == null) {
9682                 throw new IllegalArgumentException("callback must not be null");
9683             }
9684             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9685         }
9686     }
9687
9688     @Override
9689     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9690         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9691         synchronized (this) {
9692             mStackSupervisor.deleteActivityContainer(container);
9693         }
9694     }
9695
9696     @Override
9697     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9698         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9699         synchronized (this) {
9700             final int stackId = mStackSupervisor.getNextStackId();
9701             final ActivityStack stack =
9702                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9703             if (stack == null) {
9704                 return null;
9705             }
9706             return stack.mActivityContainer;
9707         }
9708     }
9709
9710     @Override
9711     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9712         synchronized (this) {
9713             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9714             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9715                 return stack.mActivityContainer.getDisplayId();
9716             }
9717             return Display.DEFAULT_DISPLAY;
9718         }
9719     }
9720
9721     @Override
9722     public int getActivityStackId(IBinder token) throws RemoteException {
9723         synchronized (this) {
9724             ActivityStack stack = ActivityRecord.getStackLocked(token);
9725             if (stack == null) {
9726                 return INVALID_STACK_ID;
9727             }
9728             return stack.mStackId;
9729         }
9730     }
9731
9732     @Override
9733     public void exitFreeformMode(IBinder token) throws RemoteException {
9734         synchronized (this) {
9735             long ident = Binder.clearCallingIdentity();
9736             try {
9737                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9738                 if (r == null) {
9739                     throw new IllegalArgumentException(
9740                             "exitFreeformMode: No activity record matching token=" + token);
9741                 }
9742                 final ActivityStack stack = r.getStackLocked(token);
9743                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9744                     throw new IllegalStateException(
9745                             "exitFreeformMode: You can only go fullscreen from freeform.");
9746                 }
9747                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9748                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9749                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9750             } finally {
9751                 Binder.restoreCallingIdentity(ident);
9752             }
9753         }
9754     }
9755
9756     @Override
9757     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9758         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9759         if (stackId == HOME_STACK_ID) {
9760             throw new IllegalArgumentException(
9761                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9762         }
9763         synchronized (this) {
9764             long ident = Binder.clearCallingIdentity();
9765             try {
9766                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9767                         + " to stackId=" + stackId + " toTop=" + toTop);
9768                 if (stackId == DOCKED_STACK_ID) {
9769                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9770                             null /* initialBounds */);
9771                 }
9772                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9773                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9774                 if (result && stackId == DOCKED_STACK_ID) {
9775                     // If task moved to docked stack - show recents if needed.
9776                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9777                             "moveTaskToDockedStack");
9778                 }
9779             } finally {
9780                 Binder.restoreCallingIdentity(ident);
9781             }
9782         }
9783     }
9784
9785     @Override
9786     public void swapDockedAndFullscreenStack() throws RemoteException {
9787         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9788         synchronized (this) {
9789             long ident = Binder.clearCallingIdentity();
9790             try {
9791                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9792                         FULLSCREEN_WORKSPACE_STACK_ID);
9793                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9794                         : null;
9795                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9796                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9797                         : null;
9798                 if (topTask == null || tasks == null || tasks.size() == 0) {
9799                     Slog.w(TAG,
9800                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9801                     return;
9802                 }
9803
9804                 // TODO: App transition
9805                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9806
9807                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9808                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9809                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9810                         ANIMATE, true /* deferResume */);
9811                 final int size = tasks.size();
9812                 for (int i = 0; i < size; i++) {
9813                     final int id = tasks.get(i).taskId;
9814                     if (id == topTask.taskId) {
9815                         continue;
9816                     }
9817                     mStackSupervisor.moveTaskToStackLocked(id,
9818                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9819                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9820                 }
9821
9822                 // Because we deferred the resume, to avoid conflicts with stack switches while
9823                 // resuming, we need to do it after all the tasks are moved.
9824                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9825                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9826
9827                 mWindowManager.executeAppTransition();
9828             } finally {
9829                 Binder.restoreCallingIdentity(ident);
9830             }
9831         }
9832     }
9833
9834     /**
9835      * Moves the input task to the docked stack.
9836      *
9837      * @param taskId Id of task to move.
9838      * @param createMode The mode the docked stack should be created in if it doesn't exist
9839      *                   already. See
9840      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9841      *                   and
9842      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9843      * @param toTop If the task and stack should be moved to the top.
9844      * @param animate Whether we should play an animation for the moving the task
9845      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9846      *                      docked stack. Pass {@code null} to use default bounds.
9847      */
9848     @Override
9849     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9850             Rect initialBounds, boolean moveHomeStackFront) {
9851         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9852         synchronized (this) {
9853             long ident = Binder.clearCallingIdentity();
9854             try {
9855                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9856                         + " to createMode=" + createMode + " toTop=" + toTop);
9857                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9858                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9859                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9860                         animate, DEFER_RESUME);
9861                 if (moved) {
9862                     if (moveHomeStackFront) {
9863                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9864                     }
9865                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9866                 }
9867                 return moved;
9868             } finally {
9869                 Binder.restoreCallingIdentity(ident);
9870             }
9871         }
9872     }
9873
9874     /**
9875      * Moves the top activity in the input stackId to the pinned stack.
9876      *
9877      * @param stackId Id of stack to move the top activity to pinned stack.
9878      * @param bounds Bounds to use for pinned stack.
9879      *
9880      * @return True if the top activity of the input stack was successfully moved to the pinned
9881      *          stack.
9882      */
9883     @Override
9884     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9885         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9886         synchronized (this) {
9887             if (!mSupportsPictureInPicture) {
9888                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9889                         + "Device doesn't support picture-in-pciture mode");
9890             }
9891
9892             long ident = Binder.clearCallingIdentity();
9893             try {
9894                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9895             } finally {
9896                 Binder.restoreCallingIdentity(ident);
9897             }
9898         }
9899     }
9900
9901     @Override
9902     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9903             boolean preserveWindows, boolean animate, int animationDuration) {
9904         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9905         long ident = Binder.clearCallingIdentity();
9906         try {
9907             synchronized (this) {
9908                 if (animate) {
9909                     if (stackId == PINNED_STACK_ID) {
9910                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9911                     } else {
9912                         throw new IllegalArgumentException("Stack: " + stackId
9913                                 + " doesn't support animated resize.");
9914                     }
9915                 } else {
9916                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9917                             null /* tempTaskInsetBounds */, preserveWindows,
9918                             allowResizeInDockedMode, !DEFER_RESUME);
9919                 }
9920             }
9921         } finally {
9922             Binder.restoreCallingIdentity(ident);
9923         }
9924     }
9925
9926     @Override
9927     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9928             Rect tempDockedTaskInsetBounds,
9929             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9930         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9931                 "resizeDockedStack()");
9932         long ident = Binder.clearCallingIdentity();
9933         try {
9934             synchronized (this) {
9935                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9936                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9937                         PRESERVE_WINDOWS);
9938             }
9939         } finally {
9940             Binder.restoreCallingIdentity(ident);
9941         }
9942     }
9943
9944     @Override
9945     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9946         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9947                 "resizePinnedStack()");
9948         final long ident = Binder.clearCallingIdentity();
9949         try {
9950             synchronized (this) {
9951                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9952             }
9953         } finally {
9954             Binder.restoreCallingIdentity(ident);
9955         }
9956     }
9957
9958     @Override
9959     public void positionTaskInStack(int taskId, int stackId, int position) {
9960         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9961         if (stackId == HOME_STACK_ID) {
9962             throw new IllegalArgumentException(
9963                     "positionTaskInStack: Attempt to change the position of task "
9964                     + taskId + " in/to home stack");
9965         }
9966         synchronized (this) {
9967             long ident = Binder.clearCallingIdentity();
9968             try {
9969                 if (DEBUG_STACK) Slog.d(TAG_STACK,
9970                         "positionTaskInStack: positioning task=" + taskId
9971                         + " in stackId=" + stackId + " at position=" + position);
9972                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9973             } finally {
9974                 Binder.restoreCallingIdentity(ident);
9975             }
9976         }
9977     }
9978
9979     @Override
9980     public List<StackInfo> getAllStackInfos() {
9981         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9982         long ident = Binder.clearCallingIdentity();
9983         try {
9984             synchronized (this) {
9985                 return mStackSupervisor.getAllStackInfosLocked();
9986             }
9987         } finally {
9988             Binder.restoreCallingIdentity(ident);
9989         }
9990     }
9991
9992     @Override
9993     public StackInfo getStackInfo(int stackId) {
9994         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9995         long ident = Binder.clearCallingIdentity();
9996         try {
9997             synchronized (this) {
9998                 return mStackSupervisor.getStackInfoLocked(stackId);
9999             }
10000         } finally {
10001             Binder.restoreCallingIdentity(ident);
10002         }
10003     }
10004
10005     @Override
10006     public boolean isInHomeStack(int taskId) {
10007         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10008         long ident = Binder.clearCallingIdentity();
10009         try {
10010             synchronized (this) {
10011                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10012                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10013                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10014             }
10015         } finally {
10016             Binder.restoreCallingIdentity(ident);
10017         }
10018     }
10019
10020     @Override
10021     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10022         synchronized(this) {
10023             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10024         }
10025     }
10026
10027     @Override
10028     public void updateDeviceOwner(String packageName) {
10029         final int callingUid = Binder.getCallingUid();
10030         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10031             throw new SecurityException("updateDeviceOwner called from non-system process");
10032         }
10033         synchronized (this) {
10034             mDeviceOwnerName = packageName;
10035         }
10036     }
10037
10038     @Override
10039     public void updateLockTaskPackages(int userId, String[] packages) {
10040         final int callingUid = Binder.getCallingUid();
10041         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10042             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10043                     "updateLockTaskPackages()");
10044         }
10045         synchronized (this) {
10046             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10047                     Arrays.toString(packages));
10048             mLockTaskPackages.put(userId, packages);
10049             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10050         }
10051     }
10052
10053
10054     void startLockTaskModeLocked(TaskRecord task) {
10055         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10056         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10057             return;
10058         }
10059
10060         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10061         // is initiated by system after the pinning request was shown and locked mode is initiated
10062         // by an authorized app directly
10063         final int callingUid = Binder.getCallingUid();
10064         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10065         long ident = Binder.clearCallingIdentity();
10066         try {
10067             if (!isSystemInitiated) {
10068                 task.mLockTaskUid = callingUid;
10069                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10070                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10071                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10072                     StatusBarManagerInternal statusBarManager =
10073                             LocalServices.getService(StatusBarManagerInternal.class);
10074                     if (statusBarManager != null) {
10075                         statusBarManager.showScreenPinningRequest(task.taskId);
10076                     }
10077                     return;
10078                 }
10079
10080                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10081                 if (stack == null || task != stack.topTask()) {
10082                     throw new IllegalArgumentException("Invalid task, not in foreground");
10083                 }
10084             }
10085             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10086                     "Locking fully");
10087             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10088                     ActivityManager.LOCK_TASK_MODE_PINNED :
10089                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10090                     "startLockTask", true);
10091         } finally {
10092             Binder.restoreCallingIdentity(ident);
10093         }
10094     }
10095
10096     @Override
10097     public void startLockTaskMode(int taskId) {
10098         synchronized (this) {
10099             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10100             if (task != null) {
10101                 startLockTaskModeLocked(task);
10102             }
10103         }
10104     }
10105
10106     @Override
10107     public void startLockTaskMode(IBinder token) {
10108         synchronized (this) {
10109             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10110             if (r == null) {
10111                 return;
10112             }
10113             final TaskRecord task = r.task;
10114             if (task != null) {
10115                 startLockTaskModeLocked(task);
10116             }
10117         }
10118     }
10119
10120     @Override
10121     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10122         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10123         // This makes inner call to look as if it was initiated by system.
10124         long ident = Binder.clearCallingIdentity();
10125         try {
10126             synchronized (this) {
10127                 startLockTaskMode(taskId);
10128             }
10129         } finally {
10130             Binder.restoreCallingIdentity(ident);
10131         }
10132     }
10133
10134     @Override
10135     public void stopLockTaskMode() {
10136         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10137         if (lockTask == null) {
10138             // Our work here is done.
10139             return;
10140         }
10141
10142         final int callingUid = Binder.getCallingUid();
10143         final int lockTaskUid = lockTask.mLockTaskUid;
10144         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10145         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10146             // Done.
10147             return;
10148         } else {
10149             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10150             // It is possible lockTaskMode was started by the system process because
10151             // android:lockTaskMode is set to a locking value in the application manifest
10152             // instead of the app calling startLockTaskMode. In this case
10153             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10154             // {@link TaskRecord.effectiveUid} instead. Also caller with
10155             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10156             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10157                     && callingUid != lockTaskUid
10158                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10159                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10160                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10161             }
10162         }
10163         long ident = Binder.clearCallingIdentity();
10164         try {
10165             Log.d(TAG, "stopLockTaskMode");
10166             // Stop lock task
10167             synchronized (this) {
10168                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10169                         "stopLockTask", true);
10170             }
10171             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10172             if (tm != null) {
10173                 tm.showInCallScreen(false);
10174             }
10175         } finally {
10176             Binder.restoreCallingIdentity(ident);
10177         }
10178     }
10179
10180     /**
10181      * This API should be called by SystemUI only when user perform certain action to dismiss
10182      * lock task mode. We should only dismiss pinned lock task mode in this case.
10183      */
10184     @Override
10185     public void stopSystemLockTaskMode() throws RemoteException {
10186         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10187             stopLockTaskMode();
10188         } else {
10189             mStackSupervisor.showLockTaskToast();
10190         }
10191     }
10192
10193     @Override
10194     public boolean isInLockTaskMode() {
10195         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10196     }
10197
10198     @Override
10199     public int getLockTaskModeState() {
10200         synchronized (this) {
10201             return mStackSupervisor.getLockTaskModeState();
10202         }
10203     }
10204
10205     @Override
10206     public void showLockTaskEscapeMessage(IBinder token) {
10207         synchronized (this) {
10208             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10209             if (r == null) {
10210                 return;
10211             }
10212             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10213         }
10214     }
10215
10216     // =========================================================
10217     // CONTENT PROVIDERS
10218     // =========================================================
10219
10220     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10221         List<ProviderInfo> providers = null;
10222         try {
10223             providers = AppGlobals.getPackageManager()
10224                     .queryContentProviders(app.processName, app.uid,
10225                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10226                                     | MATCH_DEBUG_TRIAGED_MISSING)
10227                     .getList();
10228         } catch (RemoteException ex) {
10229         }
10230         if (DEBUG_MU) Slog.v(TAG_MU,
10231                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10232         int userId = app.userId;
10233         if (providers != null) {
10234             int N = providers.size();
10235             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10236             for (int i=0; i<N; i++) {
10237                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10238                 ProviderInfo cpi =
10239                     (ProviderInfo)providers.get(i);
10240                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10241                         cpi.name, cpi.flags);
10242                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10243                     // This is a singleton provider, but a user besides the
10244                     // default user is asking to initialize a process it runs
10245                     // in...  well, no, it doesn't actually run in this process,
10246                     // it runs in the process of the default user.  Get rid of it.
10247                     providers.remove(i);
10248                     N--;
10249                     i--;
10250                     continue;
10251                 }
10252
10253                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10254                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10255                 if (cpr == null) {
10256                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10257                     mProviderMap.putProviderByClass(comp, cpr);
10258                 }
10259                 if (DEBUG_MU) Slog.v(TAG_MU,
10260                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10261                 app.pubProviders.put(cpi.name, cpr);
10262                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10263                     // Don't add this if it is a platform component that is marked
10264                     // to run in multiple processes, because this is actually
10265                     // part of the framework so doesn't make sense to track as a
10266                     // separate apk in the process.
10267                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10268                             mProcessStats);
10269                 }
10270                 notifyPackageUse(cpi.applicationInfo.packageName,
10271                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10272             }
10273         }
10274         return providers;
10275     }
10276
10277     /**
10278      * Check if {@link ProcessRecord} has a possible chance at accessing the
10279      * given {@link ProviderInfo}. Final permission checking is always done
10280      * in {@link ContentProvider}.
10281      */
10282     private final String checkContentProviderPermissionLocked(
10283             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10284         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10285         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10286         boolean checkedGrants = false;
10287         if (checkUser) {
10288             // Looking for cross-user grants before enforcing the typical cross-users permissions
10289             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10290             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10291                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10292                     return null;
10293                 }
10294                 checkedGrants = true;
10295             }
10296             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10297                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10298             if (userId != tmpTargetUserId) {
10299                 // When we actually went to determine the final targer user ID, this ended
10300                 // up different than our initial check for the authority.  This is because
10301                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10302                 // SELF.  So we need to re-check the grants again.
10303                 checkedGrants = false;
10304             }
10305         }
10306         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10307                 cpi.applicationInfo.uid, cpi.exported)
10308                 == PackageManager.PERMISSION_GRANTED) {
10309             return null;
10310         }
10311         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10312                 cpi.applicationInfo.uid, cpi.exported)
10313                 == PackageManager.PERMISSION_GRANTED) {
10314             return null;
10315         }
10316
10317         PathPermission[] pps = cpi.pathPermissions;
10318         if (pps != null) {
10319             int i = pps.length;
10320             while (i > 0) {
10321                 i--;
10322                 PathPermission pp = pps[i];
10323                 String pprperm = pp.getReadPermission();
10324                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10325                         cpi.applicationInfo.uid, cpi.exported)
10326                         == PackageManager.PERMISSION_GRANTED) {
10327                     return null;
10328                 }
10329                 String ppwperm = pp.getWritePermission();
10330                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10331                         cpi.applicationInfo.uid, cpi.exported)
10332                         == PackageManager.PERMISSION_GRANTED) {
10333                     return null;
10334                 }
10335             }
10336         }
10337         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10338             return null;
10339         }
10340
10341         String msg;
10342         if (!cpi.exported) {
10343             msg = "Permission Denial: opening provider " + cpi.name
10344                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10345                     + ", uid=" + callingUid + ") that is not exported from uid "
10346                     + cpi.applicationInfo.uid;
10347         } else {
10348             msg = "Permission Denial: opening provider " + cpi.name
10349                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10350                     + ", uid=" + callingUid + ") requires "
10351                     + cpi.readPermission + " or " + cpi.writePermission;
10352         }
10353         Slog.w(TAG, msg);
10354         return msg;
10355     }
10356
10357     /**
10358      * Returns if the ContentProvider has granted a uri to callingUid
10359      */
10360     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10361         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10362         if (perms != null) {
10363             for (int i=perms.size()-1; i>=0; i--) {
10364                 GrantUri grantUri = perms.keyAt(i);
10365                 if (grantUri.sourceUserId == userId || !checkUser) {
10366                     if (matchesProvider(grantUri.uri, cpi)) {
10367                         return true;
10368                     }
10369                 }
10370             }
10371         }
10372         return false;
10373     }
10374
10375     /**
10376      * Returns true if the uri authority is one of the authorities specified in the provider.
10377      */
10378     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10379         String uriAuth = uri.getAuthority();
10380         String cpiAuth = cpi.authority;
10381         if (cpiAuth.indexOf(';') == -1) {
10382             return cpiAuth.equals(uriAuth);
10383         }
10384         String[] cpiAuths = cpiAuth.split(";");
10385         int length = cpiAuths.length;
10386         for (int i = 0; i < length; i++) {
10387             if (cpiAuths[i].equals(uriAuth)) return true;
10388         }
10389         return false;
10390     }
10391
10392     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10393             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10394         if (r != null) {
10395             for (int i=0; i<r.conProviders.size(); i++) {
10396                 ContentProviderConnection conn = r.conProviders.get(i);
10397                 if (conn.provider == cpr) {
10398                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10399                             "Adding provider requested by "
10400                             + r.processName + " from process "
10401                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10402                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10403                     if (stable) {
10404                         conn.stableCount++;
10405                         conn.numStableIncs++;
10406                     } else {
10407                         conn.unstableCount++;
10408                         conn.numUnstableIncs++;
10409                     }
10410                     return conn;
10411                 }
10412             }
10413             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10414             if (stable) {
10415                 conn.stableCount = 1;
10416                 conn.numStableIncs = 1;
10417             } else {
10418                 conn.unstableCount = 1;
10419                 conn.numUnstableIncs = 1;
10420             }
10421             cpr.connections.add(conn);
10422             r.conProviders.add(conn);
10423             startAssociationLocked(r.uid, r.processName, r.curProcState,
10424                     cpr.uid, cpr.name, cpr.info.processName);
10425             return conn;
10426         }
10427         cpr.addExternalProcessHandleLocked(externalProcessToken);
10428         return null;
10429     }
10430
10431     boolean decProviderCountLocked(ContentProviderConnection conn,
10432             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433         if (conn != null) {
10434             cpr = conn.provider;
10435             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10436                     "Removing provider requested by "
10437                     + conn.client.processName + " from process "
10438                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10439                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10440             if (stable) {
10441                 conn.stableCount--;
10442             } else {
10443                 conn.unstableCount--;
10444             }
10445             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10446                 cpr.connections.remove(conn);
10447                 conn.client.conProviders.remove(conn);
10448                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10449                     // The client is more important than last activity -- note the time this
10450                     // is happening, so we keep the old provider process around a bit as last
10451                     // activity to avoid thrashing it.
10452                     if (cpr.proc != null) {
10453                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10454                     }
10455                 }
10456                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10457                 return true;
10458             }
10459             return false;
10460         }
10461         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10462         return false;
10463     }
10464
10465     private void checkTime(long startTime, String where) {
10466         long now = SystemClock.uptimeMillis();
10467         if ((now-startTime) > 50) {
10468             // If we are taking more than 50ms, log about it.
10469             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10470         }
10471     }
10472
10473     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10474             String name, IBinder token, boolean stable, int userId) {
10475         ContentProviderRecord cpr;
10476         ContentProviderConnection conn = null;
10477         ProviderInfo cpi = null;
10478
10479         synchronized(this) {
10480             long startTime = SystemClock.uptimeMillis();
10481
10482             ProcessRecord r = null;
10483             if (caller != null) {
10484                 r = getRecordForAppLocked(caller);
10485                 if (r == null) {
10486                     throw new SecurityException(
10487                             "Unable to find app for caller " + caller
10488                           + " (pid=" + Binder.getCallingPid()
10489                           + ") when getting content provider " + name);
10490                 }
10491             }
10492
10493             boolean checkCrossUser = true;
10494
10495             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10496
10497             // First check if this content provider has been published...
10498             cpr = mProviderMap.getProviderByName(name, userId);
10499             // If that didn't work, check if it exists for user 0 and then
10500             // verify that it's a singleton provider before using it.
10501             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10502                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10503                 if (cpr != null) {
10504                     cpi = cpr.info;
10505                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10506                             cpi.name, cpi.flags)
10507                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10508                         userId = UserHandle.USER_SYSTEM;
10509                         checkCrossUser = false;
10510                     } else {
10511                         cpr = null;
10512                         cpi = null;
10513                     }
10514                 }
10515             }
10516
10517             boolean providerRunning = cpr != null;
10518             if (providerRunning) {
10519                 cpi = cpr.info;
10520                 String msg;
10521                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10522                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10523                         != null) {
10524                     throw new SecurityException(msg);
10525                 }
10526                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10527
10528                 if (r != null && cpr.canRunHere(r)) {
10529                     // This provider has been published or is in the process
10530                     // of being published...  but it is also allowed to run
10531                     // in the caller's process, so don't make a connection
10532                     // and just let the caller instantiate its own instance.
10533                     ContentProviderHolder holder = cpr.newHolder(null);
10534                     // don't give caller the provider object, it needs
10535                     // to make its own.
10536                     holder.provider = null;
10537                     return holder;
10538                 }
10539
10540                 final long origId = Binder.clearCallingIdentity();
10541
10542                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10543
10544                 // In this case the provider instance already exists, so we can
10545                 // return it right away.
10546                 conn = incProviderCountLocked(r, cpr, token, stable);
10547                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10548                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10549                         // If this is a perceptible app accessing the provider,
10550                         // make sure to count it as being accessed and thus
10551                         // back up on the LRU list.  This is good because
10552                         // content providers are often expensive to start.
10553                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10554                         updateLruProcessLocked(cpr.proc, false, null);
10555                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10556                     }
10557                 }
10558
10559                 if (cpr.proc != null) {
10560                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10561                     boolean success = updateOomAdjLocked(cpr.proc);
10562                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10563                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10564                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10565                     // NOTE: there is still a race here where a signal could be
10566                     // pending on the process even though we managed to update its
10567                     // adj level.  Not sure what to do about this, but at least
10568                     // the race is now smaller.
10569                     if (!success) {
10570                         // Uh oh...  it looks like the provider's process
10571                         // has been killed on us.  We need to wait for a new
10572                         // process to be started, and make sure its death
10573                         // doesn't kill our process.
10574                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10575                                 + " is crashing; detaching " + r);
10576                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10577                         checkTime(startTime, "getContentProviderImpl: before appDied");
10578                         appDiedLocked(cpr.proc);
10579                         checkTime(startTime, "getContentProviderImpl: after appDied");
10580                         if (!lastRef) {
10581                             // This wasn't the last ref our process had on
10582                             // the provider...  we have now been killed, bail.
10583                             return null;
10584                         }
10585                         providerRunning = false;
10586                         conn = null;
10587                     }
10588                 }
10589
10590                 Binder.restoreCallingIdentity(origId);
10591             }
10592
10593             if (!providerRunning) {
10594                 try {
10595                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10596                     cpi = AppGlobals.getPackageManager().
10597                         resolveContentProvider(name,
10598                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10599                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10600                 } catch (RemoteException ex) {
10601                 }
10602                 if (cpi == null) {
10603                     return null;
10604                 }
10605                 // If the provider is a singleton AND
10606                 // (it's a call within the same user || the provider is a
10607                 // privileged app)
10608                 // Then allow connecting to the singleton provider
10609                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10610                         cpi.name, cpi.flags)
10611                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10612                 if (singleton) {
10613                     userId = UserHandle.USER_SYSTEM;
10614                 }
10615                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10616                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10617
10618                 String msg;
10619                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10620                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10621                         != null) {
10622                     throw new SecurityException(msg);
10623                 }
10624                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10625
10626                 if (!mProcessesReady
10627                         && !cpi.processName.equals("system")) {
10628                     // If this content provider does not run in the system
10629                     // process, and the system is not yet ready to run other
10630                     // processes, then fail fast instead of hanging.
10631                     throw new IllegalArgumentException(
10632                             "Attempt to launch content provider before system ready");
10633                 }
10634
10635                 // Make sure that the user who owns this provider is running.  If not,
10636                 // we don't want to allow it to run.
10637                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10638                     Slog.w(TAG, "Unable to launch app "
10639                             + cpi.applicationInfo.packageName + "/"
10640                             + cpi.applicationInfo.uid + " for provider "
10641                             + name + ": user " + userId + " is stopped");
10642                     return null;
10643                 }
10644
10645                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10646                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10647                 cpr = mProviderMap.getProviderByClass(comp, userId);
10648                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10649                 final boolean firstClass = cpr == null;
10650                 if (firstClass) {
10651                     final long ident = Binder.clearCallingIdentity();
10652
10653                     // If permissions need a review before any of the app components can run,
10654                     // we return no provider and launch a review activity if the calling app
10655                     // is in the foreground.
10656                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10657                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10658                             return null;
10659                         }
10660                     }
10661
10662                     try {
10663                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10664                         ApplicationInfo ai =
10665                             AppGlobals.getPackageManager().
10666                                 getApplicationInfo(
10667                                         cpi.applicationInfo.packageName,
10668                                         STOCK_PM_FLAGS, userId);
10669                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10670                         if (ai == null) {
10671                             Slog.w(TAG, "No package info for content provider "
10672                                     + cpi.name);
10673                             return null;
10674                         }
10675                         ai = getAppInfoForUser(ai, userId);
10676                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10677                     } catch (RemoteException ex) {
10678                         // pm is in same process, this will never happen.
10679                     } finally {
10680                         Binder.restoreCallingIdentity(ident);
10681                     }
10682                 }
10683
10684                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10685
10686                 if (r != null && cpr.canRunHere(r)) {
10687                     // If this is a multiprocess provider, then just return its
10688                     // info and allow the caller to instantiate it.  Only do
10689                     // this if the provider is the same user as the caller's
10690                     // process, or can run as root (so can be in any process).
10691                     return cpr.newHolder(null);
10692                 }
10693
10694                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10695                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10696                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10697
10698                 // This is single process, and our app is now connecting to it.
10699                 // See if we are already in the process of launching this
10700                 // provider.
10701                 final int N = mLaunchingProviders.size();
10702                 int i;
10703                 for (i = 0; i < N; i++) {
10704                     if (mLaunchingProviders.get(i) == cpr) {
10705                         break;
10706                     }
10707                 }
10708
10709                 // If the provider is not already being launched, then get it
10710                 // started.
10711                 if (i >= N) {
10712                     final long origId = Binder.clearCallingIdentity();
10713
10714                     try {
10715                         // Content provider is now in use, its package can't be stopped.
10716                         try {
10717                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10718                             AppGlobals.getPackageManager().setPackageStoppedState(
10719                                     cpr.appInfo.packageName, false, userId);
10720                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10721                         } catch (RemoteException e) {
10722                         } catch (IllegalArgumentException e) {
10723                             Slog.w(TAG, "Failed trying to unstop package "
10724                                     + cpr.appInfo.packageName + ": " + e);
10725                         }
10726
10727                         // Use existing process if already started
10728                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10729                         ProcessRecord proc = getProcessRecordLocked(
10730                                 cpi.processName, cpr.appInfo.uid, false);
10731                         if (proc != null && proc.thread != null) {
10732                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10733                                     "Installing in existing process " + proc);
10734                             if (!proc.pubProviders.containsKey(cpi.name)) {
10735                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10736                                 proc.pubProviders.put(cpi.name, cpr);
10737                                 try {
10738                                     proc.thread.scheduleInstallProvider(cpi);
10739                                 } catch (RemoteException e) {
10740                                 }
10741                             }
10742                         } else {
10743                             checkTime(startTime, "getContentProviderImpl: before start process");
10744                             proc = startProcessLocked(cpi.processName,
10745                                     cpr.appInfo, false, 0, "content provider",
10746                                     new ComponentName(cpi.applicationInfo.packageName,
10747                                             cpi.name), false, false, false);
10748                             checkTime(startTime, "getContentProviderImpl: after start process");
10749                             if (proc == null) {
10750                                 Slog.w(TAG, "Unable to launch app "
10751                                         + cpi.applicationInfo.packageName + "/"
10752                                         + cpi.applicationInfo.uid + " for provider "
10753                                         + name + ": process is bad");
10754                                 return null;
10755                             }
10756                         }
10757                         cpr.launchingApp = proc;
10758                         mLaunchingProviders.add(cpr);
10759                     } finally {
10760                         Binder.restoreCallingIdentity(origId);
10761                     }
10762                 }
10763
10764                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10765
10766                 // Make sure the provider is published (the same provider class
10767                 // may be published under multiple names).
10768                 if (firstClass) {
10769                     mProviderMap.putProviderByClass(comp, cpr);
10770                 }
10771
10772                 mProviderMap.putProviderByName(name, cpr);
10773                 conn = incProviderCountLocked(r, cpr, token, stable);
10774                 if (conn != null) {
10775                     conn.waiting = true;
10776                 }
10777             }
10778             checkTime(startTime, "getContentProviderImpl: done!");
10779         }
10780
10781         // Wait for the provider to be published...
10782         synchronized (cpr) {
10783             while (cpr.provider == null) {
10784                 if (cpr.launchingApp == null) {
10785                     Slog.w(TAG, "Unable to launch app "
10786                             + cpi.applicationInfo.packageName + "/"
10787                             + cpi.applicationInfo.uid + " for provider "
10788                             + name + ": launching app became null");
10789                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10790                             UserHandle.getUserId(cpi.applicationInfo.uid),
10791                             cpi.applicationInfo.packageName,
10792                             cpi.applicationInfo.uid, name);
10793                     return null;
10794                 }
10795                 try {
10796                     if (DEBUG_MU) Slog.v(TAG_MU,
10797                             "Waiting to start provider " + cpr
10798                             + " launchingApp=" + cpr.launchingApp);
10799                     if (conn != null) {
10800                         conn.waiting = true;
10801                     }
10802                     cpr.wait();
10803                 } catch (InterruptedException ex) {
10804                 } finally {
10805                     if (conn != null) {
10806                         conn.waiting = false;
10807                     }
10808                 }
10809             }
10810         }
10811         return cpr != null ? cpr.newHolder(conn) : null;
10812     }
10813
10814     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10815             ProcessRecord r, final int userId) {
10816         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10817                 cpi.packageName, userId)) {
10818
10819             final boolean callerForeground = r == null || r.setSchedGroup
10820                     != ProcessList.SCHED_GROUP_BACKGROUND;
10821
10822             // Show a permission review UI only for starting from a foreground app
10823             if (!callerForeground) {
10824                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10825                         + cpi.packageName + " requires a permissions review");
10826                 return false;
10827             }
10828
10829             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10830             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10831                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10832             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10833
10834             if (DEBUG_PERMISSIONS_REVIEW) {
10835                 Slog.i(TAG, "u" + userId + " Launching permission review "
10836                         + "for package " + cpi.packageName);
10837             }
10838
10839             final UserHandle userHandle = new UserHandle(userId);
10840             mHandler.post(new Runnable() {
10841                 @Override
10842                 public void run() {
10843                     mContext.startActivityAsUser(intent, userHandle);
10844                 }
10845             });
10846
10847             return false;
10848         }
10849
10850         return true;
10851     }
10852
10853     PackageManagerInternal getPackageManagerInternalLocked() {
10854         if (mPackageManagerInt == null) {
10855             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10856         }
10857         return mPackageManagerInt;
10858     }
10859
10860     @Override
10861     public final ContentProviderHolder getContentProvider(
10862             IApplicationThread caller, String name, int userId, boolean stable) {
10863         enforceNotIsolatedCaller("getContentProvider");
10864         if (caller == null) {
10865             String msg = "null IApplicationThread when getting content provider "
10866                     + name;
10867             Slog.w(TAG, msg);
10868             throw new SecurityException(msg);
10869         }
10870         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10871         // with cross-user grant.
10872         return getContentProviderImpl(caller, name, null, stable, userId);
10873     }
10874
10875     public ContentProviderHolder getContentProviderExternal(
10876             String name, int userId, IBinder token) {
10877         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10878             "Do not have permission in call getContentProviderExternal()");
10879         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10880                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10881         return getContentProviderExternalUnchecked(name, token, userId);
10882     }
10883
10884     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10885             IBinder token, int userId) {
10886         return getContentProviderImpl(null, name, token, true, userId);
10887     }
10888
10889     /**
10890      * Drop a content provider from a ProcessRecord's bookkeeping
10891      */
10892     public void removeContentProvider(IBinder connection, boolean stable) {
10893         enforceNotIsolatedCaller("removeContentProvider");
10894         long ident = Binder.clearCallingIdentity();
10895         try {
10896             synchronized (this) {
10897                 ContentProviderConnection conn;
10898                 try {
10899                     conn = (ContentProviderConnection)connection;
10900                 } catch (ClassCastException e) {
10901                     String msg ="removeContentProvider: " + connection
10902                             + " not a ContentProviderConnection";
10903                     Slog.w(TAG, msg);
10904                     throw new IllegalArgumentException(msg);
10905                 }
10906                 if (conn == null) {
10907                     throw new NullPointerException("connection is null");
10908                 }
10909                 if (decProviderCountLocked(conn, null, null, stable)) {
10910                     updateOomAdjLocked();
10911                 }
10912             }
10913         } finally {
10914             Binder.restoreCallingIdentity(ident);
10915         }
10916     }
10917
10918     public void removeContentProviderExternal(String name, IBinder token) {
10919         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10920             "Do not have permission in call removeContentProviderExternal()");
10921         int userId = UserHandle.getCallingUserId();
10922         long ident = Binder.clearCallingIdentity();
10923         try {
10924             removeContentProviderExternalUnchecked(name, token, userId);
10925         } finally {
10926             Binder.restoreCallingIdentity(ident);
10927         }
10928     }
10929
10930     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10931         synchronized (this) {
10932             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10933             if(cpr == null) {
10934                 //remove from mProvidersByClass
10935                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10936                 return;
10937             }
10938
10939             //update content provider record entry info
10940             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10941             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10942             if (localCpr.hasExternalProcessHandles()) {
10943                 if (localCpr.removeExternalProcessHandleLocked(token)) {
10944                     updateOomAdjLocked();
10945                 } else {
10946                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10947                             + " with no external reference for token: "
10948                             + token + ".");
10949                 }
10950             } else {
10951                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10952                         + " with no external references.");
10953             }
10954         }
10955     }
10956
10957     public final void publishContentProviders(IApplicationThread caller,
10958             List<ContentProviderHolder> providers) {
10959         if (providers == null) {
10960             return;
10961         }
10962
10963         enforceNotIsolatedCaller("publishContentProviders");
10964         synchronized (this) {
10965             final ProcessRecord r = getRecordForAppLocked(caller);
10966             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10967             if (r == null) {
10968                 throw new SecurityException(
10969                         "Unable to find app for caller " + caller
10970                       + " (pid=" + Binder.getCallingPid()
10971                       + ") when publishing content providers");
10972             }
10973
10974             final long origId = Binder.clearCallingIdentity();
10975
10976             final int N = providers.size();
10977             for (int i = 0; i < N; i++) {
10978                 ContentProviderHolder src = providers.get(i);
10979                 if (src == null || src.info == null || src.provider == null) {
10980                     continue;
10981                 }
10982                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10983                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10984                 if (dst != null) {
10985                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10986                     mProviderMap.putProviderByClass(comp, dst);
10987                     String names[] = dst.info.authority.split(";");
10988                     for (int j = 0; j < names.length; j++) {
10989                         mProviderMap.putProviderByName(names[j], dst);
10990                     }
10991
10992                     int launchingCount = mLaunchingProviders.size();
10993                     int j;
10994                     boolean wasInLaunchingProviders = false;
10995                     for (j = 0; j < launchingCount; j++) {
10996                         if (mLaunchingProviders.get(j) == dst) {
10997                             mLaunchingProviders.remove(j);
10998                             wasInLaunchingProviders = true;
10999                             j--;
11000                             launchingCount--;
11001                         }
11002                     }
11003                     if (wasInLaunchingProviders) {
11004                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11005                     }
11006                     synchronized (dst) {
11007                         dst.provider = src.provider;
11008                         dst.proc = r;
11009                         dst.notifyAll();
11010                     }
11011                     updateOomAdjLocked(r);
11012                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11013                             src.info.authority);
11014                 }
11015             }
11016
11017             Binder.restoreCallingIdentity(origId);
11018         }
11019     }
11020
11021     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11022         ContentProviderConnection conn;
11023         try {
11024             conn = (ContentProviderConnection)connection;
11025         } catch (ClassCastException e) {
11026             String msg ="refContentProvider: " + connection
11027                     + " not a ContentProviderConnection";
11028             Slog.w(TAG, msg);
11029             throw new IllegalArgumentException(msg);
11030         }
11031         if (conn == null) {
11032             throw new NullPointerException("connection is null");
11033         }
11034
11035         synchronized (this) {
11036             if (stable > 0) {
11037                 conn.numStableIncs += stable;
11038             }
11039             stable = conn.stableCount + stable;
11040             if (stable < 0) {
11041                 throw new IllegalStateException("stableCount < 0: " + stable);
11042             }
11043
11044             if (unstable > 0) {
11045                 conn.numUnstableIncs += unstable;
11046             }
11047             unstable = conn.unstableCount + unstable;
11048             if (unstable < 0) {
11049                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11050             }
11051
11052             if ((stable+unstable) <= 0) {
11053                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11054                         + stable + " unstable=" + unstable);
11055             }
11056             conn.stableCount = stable;
11057             conn.unstableCount = unstable;
11058             return !conn.dead;
11059         }
11060     }
11061
11062     public void unstableProviderDied(IBinder connection) {
11063         ContentProviderConnection conn;
11064         try {
11065             conn = (ContentProviderConnection)connection;
11066         } catch (ClassCastException e) {
11067             String msg ="refContentProvider: " + connection
11068                     + " not a ContentProviderConnection";
11069             Slog.w(TAG, msg);
11070             throw new IllegalArgumentException(msg);
11071         }
11072         if (conn == null) {
11073             throw new NullPointerException("connection is null");
11074         }
11075
11076         // Safely retrieve the content provider associated with the connection.
11077         IContentProvider provider;
11078         synchronized (this) {
11079             provider = conn.provider.provider;
11080         }
11081
11082         if (provider == null) {
11083             // Um, yeah, we're way ahead of you.
11084             return;
11085         }
11086
11087         // Make sure the caller is being honest with us.
11088         if (provider.asBinder().pingBinder()) {
11089             // Er, no, still looks good to us.
11090             synchronized (this) {
11091                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11092                         + " says " + conn + " died, but we don't agree");
11093                 return;
11094             }
11095         }
11096
11097         // Well look at that!  It's dead!
11098         synchronized (this) {
11099             if (conn.provider.provider != provider) {
11100                 // But something changed...  good enough.
11101                 return;
11102             }
11103
11104             ProcessRecord proc = conn.provider.proc;
11105             if (proc == null || proc.thread == null) {
11106                 // Seems like the process is already cleaned up.
11107                 return;
11108             }
11109
11110             // As far as we're concerned, this is just like receiving a
11111             // death notification...  just a bit prematurely.
11112             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11113                     + ") early provider death");
11114             final long ident = Binder.clearCallingIdentity();
11115             try {
11116                 appDiedLocked(proc);
11117             } finally {
11118                 Binder.restoreCallingIdentity(ident);
11119             }
11120         }
11121     }
11122
11123     @Override
11124     public void appNotRespondingViaProvider(IBinder connection) {
11125         enforceCallingPermission(
11126                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11127
11128         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11129         if (conn == null) {
11130             Slog.w(TAG, "ContentProviderConnection is null");
11131             return;
11132         }
11133
11134         final ProcessRecord host = conn.provider.proc;
11135         if (host == null) {
11136             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11137             return;
11138         }
11139
11140         mHandler.post(new Runnable() {
11141             @Override
11142             public void run() {
11143                 mAppErrors.appNotResponding(host, null, null, false,
11144                         "ContentProvider not responding");
11145             }
11146         });
11147     }
11148
11149     public final void installSystemProviders() {
11150         List<ProviderInfo> providers;
11151         synchronized (this) {
11152             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11153             providers = generateApplicationProvidersLocked(app);
11154             if (providers != null) {
11155                 for (int i=providers.size()-1; i>=0; i--) {
11156                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11157                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11158                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11159                                 + ": not system .apk");
11160                         providers.remove(i);
11161                     }
11162                 }
11163             }
11164         }
11165         if (providers != null) {
11166             mSystemThread.installSystemProviders(providers);
11167         }
11168
11169         mCoreSettingsObserver = new CoreSettingsObserver(this);
11170         mFontScaleSettingObserver = new FontScaleSettingObserver();
11171
11172         //mUsageStatsService.monitorPackages();
11173     }
11174
11175     private void startPersistentApps(int matchFlags) {
11176         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11177
11178         synchronized (this) {
11179             try {
11180                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11181                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11182                 for (ApplicationInfo app : apps) {
11183                     if (!"android".equals(app.packageName)) {
11184                         addAppLocked(app, false, null /* ABI override */);
11185                     }
11186                 }
11187             } catch (RemoteException ex) {
11188             }
11189         }
11190     }
11191
11192     /**
11193      * When a user is unlocked, we need to install encryption-unaware providers
11194      * belonging to any running apps.
11195      */
11196     private void installEncryptionUnawareProviders(int userId) {
11197         // We're only interested in providers that are encryption unaware, and
11198         // we don't care about uninstalled apps, since there's no way they're
11199         // running at this point.
11200         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11201
11202         synchronized (this) {
11203             final int NP = mProcessNames.getMap().size();
11204             for (int ip = 0; ip < NP; ip++) {
11205                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11206                 final int NA = apps.size();
11207                 for (int ia = 0; ia < NA; ia++) {
11208                     final ProcessRecord app = apps.valueAt(ia);
11209                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11210
11211                     final int NG = app.pkgList.size();
11212                     for (int ig = 0; ig < NG; ig++) {
11213                         try {
11214                             final String pkgName = app.pkgList.keyAt(ig);
11215                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11216                                     .getPackageInfo(pkgName, matchFlags, userId);
11217                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11218                                 for (ProviderInfo pi : pkgInfo.providers) {
11219                                     // TODO: keep in sync with generateApplicationProvidersLocked
11220                                     final boolean processMatch = Objects.equals(pi.processName,
11221                                             app.processName) || pi.multiprocess;
11222                                     final boolean userMatch = isSingleton(pi.processName,
11223                                             pi.applicationInfo, pi.name, pi.flags)
11224                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11225                                     if (processMatch && userMatch) {
11226                                         Log.v(TAG, "Installing " + pi);
11227                                         app.thread.scheduleInstallProvider(pi);
11228                                     } else {
11229                                         Log.v(TAG, "Skipping " + pi);
11230                                     }
11231                                 }
11232                             }
11233                         } catch (RemoteException ignored) {
11234                         }
11235                     }
11236                 }
11237             }
11238         }
11239     }
11240
11241     /**
11242      * Allows apps to retrieve the MIME type of a URI.
11243      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11244      * users, then it does not need permission to access the ContentProvider.
11245      * Either, it needs cross-user uri grants.
11246      *
11247      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11248      *
11249      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11250      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11251      */
11252     public String getProviderMimeType(Uri uri, int userId) {
11253         enforceNotIsolatedCaller("getProviderMimeType");
11254         final String name = uri.getAuthority();
11255         int callingUid = Binder.getCallingUid();
11256         int callingPid = Binder.getCallingPid();
11257         long ident = 0;
11258         boolean clearedIdentity = false;
11259         synchronized (this) {
11260             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11261         }
11262         if (canClearIdentity(callingPid, callingUid, userId)) {
11263             clearedIdentity = true;
11264             ident = Binder.clearCallingIdentity();
11265         }
11266         ContentProviderHolder holder = null;
11267         try {
11268             holder = getContentProviderExternalUnchecked(name, null, userId);
11269             if (holder != null) {
11270                 return holder.provider.getType(uri);
11271             }
11272         } catch (RemoteException e) {
11273             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11274             return null;
11275         } catch (Exception e) {
11276             Log.w(TAG, "Exception while determining type of " + uri, e);
11277             return null;
11278         } finally {
11279             // We need to clear the identity to call removeContentProviderExternalUnchecked
11280             if (!clearedIdentity) {
11281                 ident = Binder.clearCallingIdentity();
11282             }
11283             try {
11284                 if (holder != null) {
11285                     removeContentProviderExternalUnchecked(name, null, userId);
11286                 }
11287             } finally {
11288                 Binder.restoreCallingIdentity(ident);
11289             }
11290         }
11291
11292         return null;
11293     }
11294
11295     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11296         if (UserHandle.getUserId(callingUid) == userId) {
11297             return true;
11298         }
11299         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11300                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11301                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11302                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11303                 return true;
11304         }
11305         return false;
11306     }
11307
11308     // =========================================================
11309     // GLOBAL MANAGEMENT
11310     // =========================================================
11311
11312     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11313             boolean isolated, int isolatedUid) {
11314         String proc = customProcess != null ? customProcess : info.processName;
11315         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11316         final int userId = UserHandle.getUserId(info.uid);
11317         int uid = info.uid;
11318         if (isolated) {
11319             if (isolatedUid == 0) {
11320                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11321                 while (true) {
11322                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11323                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11324                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11325                     }
11326                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11327                     mNextIsolatedProcessUid++;
11328                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11329                         // No process for this uid, use it.
11330                         break;
11331                     }
11332                     stepsLeft--;
11333                     if (stepsLeft <= 0) {
11334                         return null;
11335                     }
11336                 }
11337             } else {
11338                 // Special case for startIsolatedProcess (internal only), where
11339                 // the uid of the isolated process is specified by the caller.
11340                 uid = isolatedUid;
11341             }
11342         }
11343         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11344         if (!mBooted && !mBooting
11345                 && userId == UserHandle.USER_SYSTEM
11346                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11347             r.persistent = true;
11348         }
11349         addProcessNameLocked(r);
11350         return r;
11351     }
11352
11353     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11354             String abiOverride) {
11355         ProcessRecord app;
11356         if (!isolated) {
11357             app = getProcessRecordLocked(info.processName, info.uid, true);
11358         } else {
11359             app = null;
11360         }
11361
11362         if (app == null) {
11363             app = newProcessRecordLocked(info, null, isolated, 0);
11364             updateLruProcessLocked(app, false, null);
11365             updateOomAdjLocked();
11366         }
11367
11368         // This package really, really can not be stopped.
11369         try {
11370             AppGlobals.getPackageManager().setPackageStoppedState(
11371                     info.packageName, false, UserHandle.getUserId(app.uid));
11372         } catch (RemoteException e) {
11373         } catch (IllegalArgumentException e) {
11374             Slog.w(TAG, "Failed trying to unstop package "
11375                     + info.packageName + ": " + e);
11376         }
11377
11378         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11379             app.persistent = true;
11380             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11381         }
11382         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11383             mPersistentStartingProcesses.add(app);
11384             startProcessLocked(app, "added application", app.processName, abiOverride,
11385                     null /* entryPoint */, null /* entryPointArgs */);
11386         }
11387
11388         return app;
11389     }
11390
11391     public void unhandledBack() {
11392         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11393                 "unhandledBack()");
11394
11395         synchronized(this) {
11396             final long origId = Binder.clearCallingIdentity();
11397             try {
11398                 getFocusedStack().unhandledBackLocked();
11399             } finally {
11400                 Binder.restoreCallingIdentity(origId);
11401             }
11402         }
11403     }
11404
11405     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11406         enforceNotIsolatedCaller("openContentUri");
11407         final int userId = UserHandle.getCallingUserId();
11408         String name = uri.getAuthority();
11409         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11410         ParcelFileDescriptor pfd = null;
11411         if (cph != null) {
11412             // We record the binder invoker's uid in thread-local storage before
11413             // going to the content provider to open the file.  Later, in the code
11414             // that handles all permissions checks, we look for this uid and use
11415             // that rather than the Activity Manager's own uid.  The effect is that
11416             // we do the check against the caller's permissions even though it looks
11417             // to the content provider like the Activity Manager itself is making
11418             // the request.
11419             Binder token = new Binder();
11420             sCallerIdentity.set(new Identity(
11421                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11422             try {
11423                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11424             } catch (FileNotFoundException e) {
11425                 // do nothing; pfd will be returned null
11426             } finally {
11427                 // Ensure that whatever happens, we clean up the identity state
11428                 sCallerIdentity.remove();
11429                 // Ensure we're done with the provider.
11430                 removeContentProviderExternalUnchecked(name, null, userId);
11431             }
11432         } else {
11433             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11434         }
11435         return pfd;
11436     }
11437
11438     // Actually is sleeping or shutting down or whatever else in the future
11439     // is an inactive state.
11440     public boolean isSleepingOrShuttingDown() {
11441         return isSleeping() || mShuttingDown;
11442     }
11443
11444     public boolean isSleeping() {
11445         return mSleeping;
11446     }
11447
11448     void onWakefulnessChanged(int wakefulness) {
11449         synchronized(this) {
11450             mWakefulness = wakefulness;
11451             updateSleepIfNeededLocked();
11452         }
11453     }
11454
11455     void finishRunningVoiceLocked() {
11456         if (mRunningVoice != null) {
11457             mRunningVoice = null;
11458             mVoiceWakeLock.release();
11459             updateSleepIfNeededLocked();
11460         }
11461     }
11462
11463     void startTimeTrackingFocusedActivityLocked() {
11464         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11465             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11466         }
11467     }
11468
11469     void updateSleepIfNeededLocked() {
11470         if (mSleeping && !shouldSleepLocked()) {
11471             mSleeping = false;
11472             startTimeTrackingFocusedActivityLocked();
11473             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11474             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11475             updateOomAdjLocked();
11476         } else if (!mSleeping && shouldSleepLocked()) {
11477             mSleeping = true;
11478             if (mCurAppTimeTracker != null) {
11479                 mCurAppTimeTracker.stop();
11480             }
11481             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11482             mStackSupervisor.goingToSleepLocked();
11483             updateOomAdjLocked();
11484
11485             // Initialize the wake times of all processes.
11486             checkExcessivePowerUsageLocked(false);
11487             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11488             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11489             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11490         }
11491     }
11492
11493     private boolean shouldSleepLocked() {
11494         // Resume applications while running a voice interactor.
11495         if (mRunningVoice != null) {
11496             return false;
11497         }
11498
11499         // TODO: Transform the lock screen state into a sleep token instead.
11500         switch (mWakefulness) {
11501             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11502             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11503             case PowerManagerInternal.WAKEFULNESS_DOZING:
11504                 // Pause applications whenever the lock screen is shown or any sleep
11505                 // tokens have been acquired.
11506                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11507             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11508             default:
11509                 // If we're asleep then pause applications unconditionally.
11510                 return true;
11511         }
11512     }
11513
11514     /** Pokes the task persister. */
11515     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11516         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11517     }
11518
11519     /** Notifies all listeners when the task stack has changed. */
11520     void notifyTaskStackChangedLocked() {
11521         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11522         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11523         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11524         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11525     }
11526
11527     /** Notifies all listeners when an Activity is pinned. */
11528     void notifyActivityPinnedLocked() {
11529         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11530         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11531     }
11532
11533     /**
11534      * Notifies all listeners when an attempt was made to start an an activity that is already
11535      * running in the pinned stack and the activity was not actually started, but the task is
11536      * either brought to the front or a new Intent is delivered to it.
11537      */
11538     void notifyPinnedActivityRestartAttemptLocked() {
11539         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11540         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11541     }
11542
11543     /** Notifies all listeners when the pinned stack animation ends. */
11544     @Override
11545     public void notifyPinnedStackAnimationEnded() {
11546         synchronized (this) {
11547             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11548             mHandler.obtainMessage(
11549                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11550         }
11551     }
11552
11553     @Override
11554     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11555         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11556     }
11557
11558     @Override
11559     public boolean shutdown(int timeout) {
11560         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11561                 != PackageManager.PERMISSION_GRANTED) {
11562             throw new SecurityException("Requires permission "
11563                     + android.Manifest.permission.SHUTDOWN);
11564         }
11565
11566         boolean timedout = false;
11567
11568         synchronized(this) {
11569             mShuttingDown = true;
11570             updateEventDispatchingLocked();
11571             timedout = mStackSupervisor.shutdownLocked(timeout);
11572         }
11573
11574         mAppOpsService.shutdown();
11575         if (mUsageStatsService != null) {
11576             mUsageStatsService.prepareShutdown();
11577         }
11578         mBatteryStatsService.shutdown();
11579         synchronized (this) {
11580             mProcessStats.shutdownLocked();
11581             notifyTaskPersisterLocked(null, true);
11582         }
11583
11584         return timedout;
11585     }
11586
11587     public final void activitySlept(IBinder token) {
11588         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11589
11590         final long origId = Binder.clearCallingIdentity();
11591
11592         synchronized (this) {
11593             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11594             if (r != null) {
11595                 mStackSupervisor.activitySleptLocked(r);
11596             }
11597         }
11598
11599         Binder.restoreCallingIdentity(origId);
11600     }
11601
11602     private String lockScreenShownToString() {
11603         switch (mLockScreenShown) {
11604             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11605             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11606             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11607             default: return "Unknown=" + mLockScreenShown;
11608         }
11609     }
11610
11611     void logLockScreen(String msg) {
11612         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11613                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11614                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11615                 + " mSleeping=" + mSleeping);
11616     }
11617
11618     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11619         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11620         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11621         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11622             boolean wasRunningVoice = mRunningVoice != null;
11623             mRunningVoice = session;
11624             if (!wasRunningVoice) {
11625                 mVoiceWakeLock.acquire();
11626                 updateSleepIfNeededLocked();
11627             }
11628         }
11629     }
11630
11631     private void updateEventDispatchingLocked() {
11632         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11633     }
11634
11635     public void setLockScreenShown(boolean showing, boolean occluded) {
11636         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11637                 != PackageManager.PERMISSION_GRANTED) {
11638             throw new SecurityException("Requires permission "
11639                     + android.Manifest.permission.DEVICE_POWER);
11640         }
11641
11642         synchronized(this) {
11643             long ident = Binder.clearCallingIdentity();
11644             try {
11645                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11646                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11647                 if (showing && occluded) {
11648                     // The lock screen is currently showing, but is occluded by a window that can
11649                     // show on top of the lock screen. In this can we want to dismiss the docked
11650                     // stack since it will be complicated/risky to try to put the activity on top
11651                     // of the lock screen in the right fullscreen configuration.
11652                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11653                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11654                 }
11655
11656                 updateSleepIfNeededLocked();
11657             } finally {
11658                 Binder.restoreCallingIdentity(ident);
11659             }
11660         }
11661     }
11662
11663     @Override
11664     public void notifyLockedProfile(@UserIdInt int userId) {
11665         try {
11666             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11667                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11668             }
11669         } catch (RemoteException ex) {
11670             throw new SecurityException("Fail to check is caller a privileged app", ex);
11671         }
11672
11673         synchronized (this) {
11674             if (mStackSupervisor.isUserLockedProfile(userId)) {
11675                 final long ident = Binder.clearCallingIdentity();
11676                 try {
11677                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11678                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11679                         // If there is no device lock, we will show the profile's credential page.
11680                         mActivityStarter.showConfirmDeviceCredential(userId);
11681                     } else {
11682                         // Showing launcher to avoid user entering credential twice.
11683                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11684                     }
11685                 } finally {
11686                     Binder.restoreCallingIdentity(ident);
11687                 }
11688             }
11689         }
11690     }
11691
11692     @Override
11693     public void startConfirmDeviceCredentialIntent(Intent intent) {
11694         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11695         synchronized (this) {
11696             final long ident = Binder.clearCallingIdentity();
11697             try {
11698                 mActivityStarter.startConfirmCredentialIntent(intent);
11699             } finally {
11700                 Binder.restoreCallingIdentity(ident);
11701             }
11702         }
11703     }
11704
11705     @Override
11706     public void stopAppSwitches() {
11707         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11708                 != PackageManager.PERMISSION_GRANTED) {
11709             throw new SecurityException("viewquires permission "
11710                     + android.Manifest.permission.STOP_APP_SWITCHES);
11711         }
11712
11713         synchronized(this) {
11714             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11715                     + APP_SWITCH_DELAY_TIME;
11716             mDidAppSwitch = false;
11717             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11718             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11719             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11720         }
11721     }
11722
11723     public void resumeAppSwitches() {
11724         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11725                 != PackageManager.PERMISSION_GRANTED) {
11726             throw new SecurityException("Requires permission "
11727                     + android.Manifest.permission.STOP_APP_SWITCHES);
11728         }
11729
11730         synchronized(this) {
11731             // Note that we don't execute any pending app switches... we will
11732             // let those wait until either the timeout, or the next start
11733             // activity request.
11734             mAppSwitchesAllowedTime = 0;
11735         }
11736     }
11737
11738     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11739             int callingPid, int callingUid, String name) {
11740         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11741             return true;
11742         }
11743
11744         int perm = checkComponentPermission(
11745                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11746                 sourceUid, -1, true);
11747         if (perm == PackageManager.PERMISSION_GRANTED) {
11748             return true;
11749         }
11750
11751         // If the actual IPC caller is different from the logical source, then
11752         // also see if they are allowed to control app switches.
11753         if (callingUid != -1 && callingUid != sourceUid) {
11754             perm = checkComponentPermission(
11755                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11756                     callingUid, -1, true);
11757             if (perm == PackageManager.PERMISSION_GRANTED) {
11758                 return true;
11759             }
11760         }
11761
11762         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11763         return false;
11764     }
11765
11766     public void setDebugApp(String packageName, boolean waitForDebugger,
11767             boolean persistent) {
11768         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11769                 "setDebugApp()");
11770
11771         long ident = Binder.clearCallingIdentity();
11772         try {
11773             // Note that this is not really thread safe if there are multiple
11774             // callers into it at the same time, but that's not a situation we
11775             // care about.
11776             if (persistent) {
11777                 final ContentResolver resolver = mContext.getContentResolver();
11778                 Settings.Global.putString(
11779                     resolver, Settings.Global.DEBUG_APP,
11780                     packageName);
11781                 Settings.Global.putInt(
11782                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11783                     waitForDebugger ? 1 : 0);
11784             }
11785
11786             synchronized (this) {
11787                 if (!persistent) {
11788                     mOrigDebugApp = mDebugApp;
11789                     mOrigWaitForDebugger = mWaitForDebugger;
11790                 }
11791                 mDebugApp = packageName;
11792                 mWaitForDebugger = waitForDebugger;
11793                 mDebugTransient = !persistent;
11794                 if (packageName != null) {
11795                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11796                             false, UserHandle.USER_ALL, "set debug app");
11797                 }
11798             }
11799         } finally {
11800             Binder.restoreCallingIdentity(ident);
11801         }
11802     }
11803
11804     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11805         synchronized (this) {
11806             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11807             if (!isDebuggable) {
11808                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11809                     throw new SecurityException("Process not debuggable: " + app.packageName);
11810                 }
11811             }
11812
11813             mTrackAllocationApp = processName;
11814         }
11815     }
11816
11817     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11818         synchronized (this) {
11819             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11820             if (!isDebuggable) {
11821                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11822                     throw new SecurityException("Process not debuggable: " + app.packageName);
11823                 }
11824             }
11825             mProfileApp = processName;
11826             mProfileFile = profilerInfo.profileFile;
11827             if (mProfileFd != null) {
11828                 try {
11829                     mProfileFd.close();
11830                 } catch (IOException e) {
11831                 }
11832                 mProfileFd = null;
11833             }
11834             mProfileFd = profilerInfo.profileFd;
11835             mSamplingInterval = profilerInfo.samplingInterval;
11836             mAutoStopProfiler = profilerInfo.autoStopProfiler;
11837             mProfileType = 0;
11838         }
11839     }
11840
11841     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11842         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11843         if (!isDebuggable) {
11844             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11845                 throw new SecurityException("Process not debuggable: " + app.packageName);
11846             }
11847         }
11848         mNativeDebuggingApp = processName;
11849     }
11850
11851     @Override
11852     public void setAlwaysFinish(boolean enabled) {
11853         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11854                 "setAlwaysFinish()");
11855
11856         long ident = Binder.clearCallingIdentity();
11857         try {
11858             Settings.Global.putInt(
11859                     mContext.getContentResolver(),
11860                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11861
11862             synchronized (this) {
11863                 mAlwaysFinishActivities = enabled;
11864             }
11865         } finally {
11866             Binder.restoreCallingIdentity(ident);
11867         }
11868     }
11869
11870     @Override
11871     public void setLenientBackgroundCheck(boolean enabled) {
11872         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11873                 "setLenientBackgroundCheck()");
11874
11875         long ident = Binder.clearCallingIdentity();
11876         try {
11877             Settings.Global.putInt(
11878                     mContext.getContentResolver(),
11879                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11880
11881             synchronized (this) {
11882                 mLenientBackgroundCheck = enabled;
11883             }
11884         } finally {
11885             Binder.restoreCallingIdentity(ident);
11886         }
11887     }
11888
11889     @Override
11890     public void setActivityController(IActivityController controller, boolean imAMonkey) {
11891         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11892                 "setActivityController()");
11893         synchronized (this) {
11894             mController = controller;
11895             mControllerIsAMonkey = imAMonkey;
11896             Watchdog.getInstance().setActivityController(controller);
11897         }
11898     }
11899
11900     @Override
11901     public void setUserIsMonkey(boolean userIsMonkey) {
11902         synchronized (this) {
11903             synchronized (mPidsSelfLocked) {
11904                 final int callingPid = Binder.getCallingPid();
11905                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11906                 if (precessRecord == null) {
11907                     throw new SecurityException("Unknown process: " + callingPid);
11908                 }
11909                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
11910                     throw new SecurityException("Only an instrumentation process "
11911                             + "with a UiAutomation can call setUserIsMonkey");
11912                 }
11913             }
11914             mUserIsMonkey = userIsMonkey;
11915         }
11916     }
11917
11918     @Override
11919     public boolean isUserAMonkey() {
11920         synchronized (this) {
11921             // If there is a controller also implies the user is a monkey.
11922             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11923         }
11924     }
11925
11926     public void requestBugReport(int bugreportType) {
11927         String service = null;
11928         switch (bugreportType) {
11929             case ActivityManager.BUGREPORT_OPTION_FULL:
11930                 service = "bugreport";
11931                 break;
11932             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11933                 service = "bugreportplus";
11934                 break;
11935             case ActivityManager.BUGREPORT_OPTION_REMOTE:
11936                 service = "bugreportremote";
11937                 break;
11938         }
11939         if (service == null) {
11940             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11941                     + bugreportType);
11942         }
11943         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11944         SystemProperties.set("ctl.start", service);
11945     }
11946
11947     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11948         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11949     }
11950
11951     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11952         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11953             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11954         }
11955         return KEY_DISPATCHING_TIMEOUT;
11956     }
11957
11958     @Override
11959     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11960         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11961                 != PackageManager.PERMISSION_GRANTED) {
11962             throw new SecurityException("Requires permission "
11963                     + android.Manifest.permission.FILTER_EVENTS);
11964         }
11965         ProcessRecord proc;
11966         long timeout;
11967         synchronized (this) {
11968             synchronized (mPidsSelfLocked) {
11969                 proc = mPidsSelfLocked.get(pid);
11970             }
11971             timeout = getInputDispatchingTimeoutLocked(proc);
11972         }
11973
11974         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11975             return -1;
11976         }
11977
11978         return timeout;
11979     }
11980
11981     /**
11982      * Handle input dispatching timeouts.
11983      * Returns whether input dispatching should be aborted or not.
11984      */
11985     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11986             final ActivityRecord activity, final ActivityRecord parent,
11987             final boolean aboveSystem, String reason) {
11988         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11989                 != PackageManager.PERMISSION_GRANTED) {
11990             throw new SecurityException("Requires permission "
11991                     + android.Manifest.permission.FILTER_EVENTS);
11992         }
11993
11994         final String annotation;
11995         if (reason == null) {
11996             annotation = "Input dispatching timed out";
11997         } else {
11998             annotation = "Input dispatching timed out (" + reason + ")";
11999         }
12000
12001         if (proc != null) {
12002             synchronized (this) {
12003                 if (proc.debugging) {
12004                     return false;
12005                 }
12006
12007                 if (mDidDexOpt) {
12008                     // Give more time since we were dexopting.
12009                     mDidDexOpt = false;
12010                     return false;
12011                 }
12012
12013                 if (proc.instrumentationClass != null) {
12014                     Bundle info = new Bundle();
12015                     info.putString("shortMsg", "keyDispatchingTimedOut");
12016                     info.putString("longMsg", annotation);
12017                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12018                     return true;
12019                 }
12020             }
12021             mHandler.post(new Runnable() {
12022                 @Override
12023                 public void run() {
12024                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12025                 }
12026             });
12027         }
12028
12029         return true;
12030     }
12031
12032     @Override
12033     public Bundle getAssistContextExtras(int requestType) {
12034         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12035                 null, null, true /* focused */, true /* newSessionId */,
12036                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12037         if (pae == null) {
12038             return null;
12039         }
12040         synchronized (pae) {
12041             while (!pae.haveResult) {
12042                 try {
12043                     pae.wait();
12044                 } catch (InterruptedException e) {
12045                 }
12046             }
12047         }
12048         synchronized (this) {
12049             buildAssistBundleLocked(pae, pae.result);
12050             mPendingAssistExtras.remove(pae);
12051             mUiHandler.removeCallbacks(pae);
12052         }
12053         return pae.extras;
12054     }
12055
12056     @Override
12057     public boolean isAssistDataAllowedOnCurrentActivity() {
12058         int userId;
12059         synchronized (this) {
12060             userId = mUserController.getCurrentUserIdLocked();
12061             ActivityRecord activity = getFocusedStack().topActivity();
12062             if (activity == null) {
12063                 return false;
12064             }
12065             userId = activity.userId;
12066         }
12067         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12068                 Context.DEVICE_POLICY_SERVICE);
12069         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12070     }
12071
12072     @Override
12073     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12074         long ident = Binder.clearCallingIdentity();
12075         try {
12076             synchronized (this) {
12077                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12078                 ActivityRecord top = getFocusedStack().topActivity();
12079                 if (top != caller) {
12080                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12081                             + " is not current top " + top);
12082                     return false;
12083                 }
12084                 if (!top.nowVisible) {
12085                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12086                             + " is not visible");
12087                     return false;
12088                 }
12089             }
12090             AssistUtils utils = new AssistUtils(mContext);
12091             return utils.showSessionForActiveService(args,
12092                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12093         } finally {
12094             Binder.restoreCallingIdentity(ident);
12095         }
12096     }
12097
12098     @Override
12099     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12100             Bundle receiverExtras,
12101             IBinder activityToken, boolean focused, boolean newSessionId) {
12102         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12103                 activityToken, focused, newSessionId,
12104                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12105                 != null;
12106     }
12107
12108     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12109             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12110             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12111         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12112                 "enqueueAssistContext()");
12113         synchronized (this) {
12114             ActivityRecord activity = getFocusedStack().topActivity();
12115             if (activity == null) {
12116                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12117                 return null;
12118             }
12119             if (activity.app == null || activity.app.thread == null) {
12120                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12121                 return null;
12122             }
12123             if (focused) {
12124                 if (activityToken != null) {
12125                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12126                     if (activity != caller) {
12127                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12128                                 + " is not current top " + activity);
12129                         return null;
12130                     }
12131                 }
12132             } else {
12133                 activity = ActivityRecord.forTokenLocked(activityToken);
12134                 if (activity == null) {
12135                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12136                             + " couldn't be found");
12137                     return null;
12138                 }
12139             }
12140
12141             PendingAssistExtras pae;
12142             Bundle extras = new Bundle();
12143             if (args != null) {
12144                 extras.putAll(args);
12145             }
12146             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12147             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12148             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12149                     userHandle);
12150             // Increment the sessionId if necessary
12151             if (newSessionId) {
12152                 mViSessionId++;
12153             }
12154             try {
12155                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12156                         requestType, mViSessionId);
12157                 mPendingAssistExtras.add(pae);
12158                 mUiHandler.postDelayed(pae, timeout);
12159             } catch (RemoteException e) {
12160                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12161                 return null;
12162             }
12163             return pae;
12164         }
12165     }
12166
12167     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12168         IResultReceiver receiver;
12169         synchronized (this) {
12170             mPendingAssistExtras.remove(pae);
12171             receiver = pae.receiver;
12172         }
12173         if (receiver != null) {
12174             // Caller wants result sent back to them.
12175             Bundle sendBundle = new Bundle();
12176             // At least return the receiver extras
12177             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12178                     pae.receiverExtras);
12179             try {
12180                 pae.receiver.send(0, sendBundle);
12181             } catch (RemoteException e) {
12182             }
12183         }
12184     }
12185
12186     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12187         if (result != null) {
12188             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12189         }
12190         if (pae.hint != null) {
12191             pae.extras.putBoolean(pae.hint, true);
12192         }
12193     }
12194
12195     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12196             AssistContent content, Uri referrer) {
12197         PendingAssistExtras pae = (PendingAssistExtras)token;
12198         synchronized (pae) {
12199             pae.result = extras;
12200             pae.structure = structure;
12201             pae.content = content;
12202             if (referrer != null) {
12203                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12204             }
12205             pae.haveResult = true;
12206             pae.notifyAll();
12207             if (pae.intent == null && pae.receiver == null) {
12208                 // Caller is just waiting for the result.
12209                 return;
12210             }
12211         }
12212
12213         // We are now ready to launch the assist activity.
12214         IResultReceiver sendReceiver = null;
12215         Bundle sendBundle = null;
12216         synchronized (this) {
12217             buildAssistBundleLocked(pae, extras);
12218             boolean exists = mPendingAssistExtras.remove(pae);
12219             mUiHandler.removeCallbacks(pae);
12220             if (!exists) {
12221                 // Timed out.
12222                 return;
12223             }
12224             if ((sendReceiver=pae.receiver) != null) {
12225                 // Caller wants result sent back to them.
12226                 sendBundle = new Bundle();
12227                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12228                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12229                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12230                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12231                         pae.receiverExtras);
12232             }
12233         }
12234         if (sendReceiver != null) {
12235             try {
12236                 sendReceiver.send(0, sendBundle);
12237             } catch (RemoteException e) {
12238             }
12239             return;
12240         }
12241
12242         long ident = Binder.clearCallingIdentity();
12243         try {
12244             pae.intent.replaceExtras(pae.extras);
12245             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12246                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12247                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12248             closeSystemDialogs("assist");
12249             try {
12250                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12251             } catch (ActivityNotFoundException e) {
12252                 Slog.w(TAG, "No activity to handle assist action.", e);
12253             }
12254         } finally {
12255             Binder.restoreCallingIdentity(ident);
12256         }
12257     }
12258
12259     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12260             Bundle args) {
12261         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12262                 true /* focused */, true /* newSessionId */,
12263                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12264     }
12265
12266     public void registerProcessObserver(IProcessObserver observer) {
12267         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12268                 "registerProcessObserver()");
12269         synchronized (this) {
12270             mProcessObservers.register(observer);
12271         }
12272     }
12273
12274     @Override
12275     public void unregisterProcessObserver(IProcessObserver observer) {
12276         synchronized (this) {
12277             mProcessObservers.unregister(observer);
12278         }
12279     }
12280
12281     @Override
12282     public void registerUidObserver(IUidObserver observer, int which) {
12283         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12284                 "registerUidObserver()");
12285         synchronized (this) {
12286             mUidObservers.register(observer, which);
12287         }
12288     }
12289
12290     @Override
12291     public void unregisterUidObserver(IUidObserver observer) {
12292         synchronized (this) {
12293             mUidObservers.unregister(observer);
12294         }
12295     }
12296
12297     @Override
12298     public boolean convertFromTranslucent(IBinder token) {
12299         final long origId = Binder.clearCallingIdentity();
12300         try {
12301             synchronized (this) {
12302                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12303                 if (r == null) {
12304                     return false;
12305                 }
12306                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12307                 if (translucentChanged) {
12308                     r.task.stack.releaseBackgroundResources(r);
12309                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12310                 }
12311                 mWindowManager.setAppFullscreen(token, true);
12312                 return translucentChanged;
12313             }
12314         } finally {
12315             Binder.restoreCallingIdentity(origId);
12316         }
12317     }
12318
12319     @Override
12320     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12321         final long origId = Binder.clearCallingIdentity();
12322         try {
12323             synchronized (this) {
12324                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12325                 if (r == null) {
12326                     return false;
12327                 }
12328                 int index = r.task.mActivities.lastIndexOf(r);
12329                 if (index > 0) {
12330                     ActivityRecord under = r.task.mActivities.get(index - 1);
12331                     under.returningOptions = options;
12332                 }
12333                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12334                 if (translucentChanged) {
12335                     r.task.stack.convertActivityToTranslucent(r);
12336                 }
12337                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12338                 mWindowManager.setAppFullscreen(token, false);
12339                 return translucentChanged;
12340             }
12341         } finally {
12342             Binder.restoreCallingIdentity(origId);
12343         }
12344     }
12345
12346     @Override
12347     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12348         final long origId = Binder.clearCallingIdentity();
12349         try {
12350             synchronized (this) {
12351                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12352                 if (r != null) {
12353                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12354                 }
12355             }
12356             return false;
12357         } finally {
12358             Binder.restoreCallingIdentity(origId);
12359         }
12360     }
12361
12362     @Override
12363     public boolean isBackgroundVisibleBehind(IBinder token) {
12364         final long origId = Binder.clearCallingIdentity();
12365         try {
12366             synchronized (this) {
12367                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12368                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12369                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12370                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12371                 return visible;
12372             }
12373         } finally {
12374             Binder.restoreCallingIdentity(origId);
12375         }
12376     }
12377
12378     @Override
12379     public ActivityOptions getActivityOptions(IBinder token) {
12380         final long origId = Binder.clearCallingIdentity();
12381         try {
12382             synchronized (this) {
12383                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12384                 if (r != null) {
12385                     final ActivityOptions activityOptions = r.pendingOptions;
12386                     r.pendingOptions = null;
12387                     return activityOptions;
12388                 }
12389                 return null;
12390             }
12391         } finally {
12392             Binder.restoreCallingIdentity(origId);
12393         }
12394     }
12395
12396     @Override
12397     public void setImmersive(IBinder token, boolean immersive) {
12398         synchronized(this) {
12399             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12400             if (r == null) {
12401                 throw new IllegalArgumentException();
12402             }
12403             r.immersive = immersive;
12404
12405             // update associated state if we're frontmost
12406             if (r == mFocusedActivity) {
12407                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12408                 applyUpdateLockStateLocked(r);
12409             }
12410         }
12411     }
12412
12413     @Override
12414     public boolean isImmersive(IBinder token) {
12415         synchronized (this) {
12416             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12417             if (r == null) {
12418                 throw new IllegalArgumentException();
12419             }
12420             return r.immersive;
12421         }
12422     }
12423
12424     @Override
12425     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12426         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12427             throw new UnsupportedOperationException("VR mode not supported on this device!");
12428         }
12429
12430         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12431
12432         ActivityRecord r;
12433         synchronized (this) {
12434             r = ActivityRecord.isInStackLocked(token);
12435         }
12436
12437         if (r == null) {
12438             throw new IllegalArgumentException();
12439         }
12440
12441         int err;
12442         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12443                 VrManagerInternal.NO_ERROR) {
12444             return err;
12445         }
12446
12447         synchronized(this) {
12448             r.requestedVrComponent = (enabled) ? packageName : null;
12449
12450             // Update associated state if this activity is currently focused
12451             if (r == mFocusedActivity) {
12452                 applyUpdateVrModeLocked(r);
12453             }
12454             return 0;
12455         }
12456     }
12457
12458     @Override
12459     public boolean isVrModePackageEnabled(ComponentName packageName) {
12460         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12461             throw new UnsupportedOperationException("VR mode not supported on this device!");
12462         }
12463
12464         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12465
12466         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12467                 VrManagerInternal.NO_ERROR;
12468     }
12469
12470     public boolean isTopActivityImmersive() {
12471         enforceNotIsolatedCaller("startActivity");
12472         synchronized (this) {
12473             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12474             return (r != null) ? r.immersive : false;
12475         }
12476     }
12477
12478     @Override
12479     public boolean isTopOfTask(IBinder token) {
12480         synchronized (this) {
12481             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12482             if (r == null) {
12483                 throw new IllegalArgumentException();
12484             }
12485             return r.task.getTopActivity() == r;
12486         }
12487     }
12488
12489     public final void enterSafeMode() {
12490         synchronized(this) {
12491             // It only makes sense to do this before the system is ready
12492             // and started launching other packages.
12493             if (!mSystemReady) {
12494                 try {
12495                     AppGlobals.getPackageManager().enterSafeMode();
12496                 } catch (RemoteException e) {
12497                 }
12498             }
12499
12500             mSafeMode = true;
12501         }
12502     }
12503
12504     public final void showSafeModeOverlay() {
12505         View v = LayoutInflater.from(mContext).inflate(
12506                 com.android.internal.R.layout.safe_mode, null);
12507         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12508         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12509         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12510         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12511         lp.gravity = Gravity.BOTTOM | Gravity.START;
12512         lp.format = v.getBackground().getOpacity();
12513         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12514                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12515         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12516         ((WindowManager)mContext.getSystemService(
12517                 Context.WINDOW_SERVICE)).addView(v, lp);
12518     }
12519
12520     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12521         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12522             return;
12523         }
12524         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12525         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12526         synchronized (stats) {
12527             if (mBatteryStatsService.isOnBattery()) {
12528                 mBatteryStatsService.enforceCallingPermission();
12529                 int MY_UID = Binder.getCallingUid();
12530                 final int uid;
12531                 if (sender == null) {
12532                     uid = sourceUid;
12533                 } else {
12534                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12535                 }
12536                 BatteryStatsImpl.Uid.Pkg pkg =
12537                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12538                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12539                 pkg.noteWakeupAlarmLocked(tag);
12540             }
12541         }
12542     }
12543
12544     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12545         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12546             return;
12547         }
12548         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12549         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12550         synchronized (stats) {
12551             mBatteryStatsService.enforceCallingPermission();
12552             int MY_UID = Binder.getCallingUid();
12553             final int uid;
12554             if (sender == null) {
12555                 uid = sourceUid;
12556             } else {
12557                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12558             }
12559             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12560         }
12561     }
12562
12563     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12564         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12565             return;
12566         }
12567         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12568         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12569         synchronized (stats) {
12570             mBatteryStatsService.enforceCallingPermission();
12571             int MY_UID = Binder.getCallingUid();
12572             final int uid;
12573             if (sender == null) {
12574                 uid = sourceUid;
12575             } else {
12576                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12577             }
12578             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12579         }
12580     }
12581
12582     public boolean killPids(int[] pids, String pReason, boolean secure) {
12583         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12584             throw new SecurityException("killPids only available to the system");
12585         }
12586         String reason = (pReason == null) ? "Unknown" : pReason;
12587         // XXX Note: don't acquire main activity lock here, because the window
12588         // manager calls in with its locks held.
12589
12590         boolean killed = false;
12591         synchronized (mPidsSelfLocked) {
12592             int worstType = 0;
12593             for (int i=0; i<pids.length; i++) {
12594                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12595                 if (proc != null) {
12596                     int type = proc.setAdj;
12597                     if (type > worstType) {
12598                         worstType = type;
12599                     }
12600                 }
12601             }
12602
12603             // If the worst oom_adj is somewhere in the cached proc LRU range,
12604             // then constrain it so we will kill all cached procs.
12605             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12606                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12607                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12608             }
12609
12610             // If this is not a secure call, don't let it kill processes that
12611             // are important.
12612             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12613                 worstType = ProcessList.SERVICE_ADJ;
12614             }
12615
12616             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12617             for (int i=0; i<pids.length; i++) {
12618                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12619                 if (proc == null) {
12620                     continue;
12621                 }
12622                 int adj = proc.setAdj;
12623                 if (adj >= worstType && !proc.killedByAm) {
12624                     proc.kill(reason, true);
12625                     killed = true;
12626                 }
12627             }
12628         }
12629         return killed;
12630     }
12631
12632     @Override
12633     public void killUid(int appId, int userId, String reason) {
12634         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12635         synchronized (this) {
12636             final long identity = Binder.clearCallingIdentity();
12637             try {
12638                 killPackageProcessesLocked(null, appId, userId,
12639                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12640                         reason != null ? reason : "kill uid");
12641             } finally {
12642                 Binder.restoreCallingIdentity(identity);
12643             }
12644         }
12645     }
12646
12647     @Override
12648     public boolean killProcessesBelowForeground(String reason) {
12649         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12650             throw new SecurityException("killProcessesBelowForeground() only available to system");
12651         }
12652
12653         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12654     }
12655
12656     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12657         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12658             throw new SecurityException("killProcessesBelowAdj() only available to system");
12659         }
12660
12661         boolean killed = false;
12662         synchronized (mPidsSelfLocked) {
12663             final int size = mPidsSelfLocked.size();
12664             for (int i = 0; i < size; i++) {
12665                 final int pid = mPidsSelfLocked.keyAt(i);
12666                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12667                 if (proc == null) continue;
12668
12669                 final int adj = proc.setAdj;
12670                 if (adj > belowAdj && !proc.killedByAm) {
12671                     proc.kill(reason, true);
12672                     killed = true;
12673                 }
12674             }
12675         }
12676         return killed;
12677     }
12678
12679     @Override
12680     public void hang(final IBinder who, boolean allowRestart) {
12681         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12682                 != PackageManager.PERMISSION_GRANTED) {
12683             throw new SecurityException("Requires permission "
12684                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12685         }
12686
12687         final IBinder.DeathRecipient death = new DeathRecipient() {
12688             @Override
12689             public void binderDied() {
12690                 synchronized (this) {
12691                     notifyAll();
12692                 }
12693             }
12694         };
12695
12696         try {
12697             who.linkToDeath(death, 0);
12698         } catch (RemoteException e) {
12699             Slog.w(TAG, "hang: given caller IBinder is already dead.");
12700             return;
12701         }
12702
12703         synchronized (this) {
12704             Watchdog.getInstance().setAllowRestart(allowRestart);
12705             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12706             synchronized (death) {
12707                 while (who.isBinderAlive()) {
12708                     try {
12709                         death.wait();
12710                     } catch (InterruptedException e) {
12711                     }
12712                 }
12713             }
12714             Watchdog.getInstance().setAllowRestart(true);
12715         }
12716     }
12717
12718     @Override
12719     public void restart() {
12720         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12721                 != PackageManager.PERMISSION_GRANTED) {
12722             throw new SecurityException("Requires permission "
12723                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12724         }
12725
12726         Log.i(TAG, "Sending shutdown broadcast...");
12727
12728         BroadcastReceiver br = new BroadcastReceiver() {
12729             @Override public void onReceive(Context context, Intent intent) {
12730                 // Now the broadcast is done, finish up the low-level shutdown.
12731                 Log.i(TAG, "Shutting down activity manager...");
12732                 shutdown(10000);
12733                 Log.i(TAG, "Shutdown complete, restarting!");
12734                 Process.killProcess(Process.myPid());
12735                 System.exit(10);
12736             }
12737         };
12738
12739         // First send the high-level shut down broadcast.
12740         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12741         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12742         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12743         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12744         mContext.sendOrderedBroadcastAsUser(intent,
12745                 UserHandle.ALL, null, br, mHandler, 0, null, null);
12746         */
12747         br.onReceive(mContext, intent);
12748     }
12749
12750     private long getLowRamTimeSinceIdle(long now) {
12751         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12752     }
12753
12754     @Override
12755     public void performIdleMaintenance() {
12756         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12757                 != PackageManager.PERMISSION_GRANTED) {
12758             throw new SecurityException("Requires permission "
12759                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12760         }
12761
12762         synchronized (this) {
12763             final long now = SystemClock.uptimeMillis();
12764             final long timeSinceLastIdle = now - mLastIdleTime;
12765             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12766             mLastIdleTime = now;
12767             mLowRamTimeSinceLastIdle = 0;
12768             if (mLowRamStartTime != 0) {
12769                 mLowRamStartTime = now;
12770             }
12771
12772             StringBuilder sb = new StringBuilder(128);
12773             sb.append("Idle maintenance over ");
12774             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12775             sb.append(" low RAM for ");
12776             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12777             Slog.i(TAG, sb.toString());
12778
12779             // If at least 1/3 of our time since the last idle period has been spent
12780             // with RAM low, then we want to kill processes.
12781             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12782
12783             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12784                 ProcessRecord proc = mLruProcesses.get(i);
12785                 if (proc.notCachedSinceIdle) {
12786                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12787                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12788                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12789                         if (doKilling && proc.initialIdlePss != 0
12790                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12791                             sb = new StringBuilder(128);
12792                             sb.append("Kill");
12793                             sb.append(proc.processName);
12794                             sb.append(" in idle maint: pss=");
12795                             sb.append(proc.lastPss);
12796                             sb.append(", swapPss=");
12797                             sb.append(proc.lastSwapPss);
12798                             sb.append(", initialPss=");
12799                             sb.append(proc.initialIdlePss);
12800                             sb.append(", period=");
12801                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12802                             sb.append(", lowRamPeriod=");
12803                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12804                             Slog.wtfQuiet(TAG, sb.toString());
12805                             proc.kill("idle maint (pss " + proc.lastPss
12806                                     + " from " + proc.initialIdlePss + ")", true);
12807                         }
12808                     }
12809                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12810                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12811                     proc.notCachedSinceIdle = true;
12812                     proc.initialIdlePss = 0;
12813                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12814                             mTestPssMode, isSleeping(), now);
12815                 }
12816             }
12817
12818             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12819             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12820         }
12821     }
12822
12823     @Override
12824     public void sendIdleJobTrigger() {
12825         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12826                 != PackageManager.PERMISSION_GRANTED) {
12827             throw new SecurityException("Requires permission "
12828                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12829         }
12830
12831         final long ident = Binder.clearCallingIdentity();
12832         try {
12833             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12834                     .setPackage("android")
12835                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12836             broadcastIntent(null, intent, null, null, 0, null, null, null,
12837                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12838         } finally {
12839             Binder.restoreCallingIdentity(ident);
12840         }
12841     }
12842
12843     private void retrieveSettings() {
12844         final ContentResolver resolver = mContext.getContentResolver();
12845         final boolean freeformWindowManagement =
12846                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12847                         || Settings.Global.getInt(
12848                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12849         final boolean supportsPictureInPicture =
12850                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12851
12852         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12853         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12854         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12855         final boolean alwaysFinishActivities =
12856                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12857         final boolean lenientBackgroundCheck =
12858                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12859         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12860         final boolean forceResizable = Settings.Global.getInt(
12861                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12862         final boolean supportsLeanbackOnly =
12863                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12864
12865         // Transfer any global setting for forcing RTL layout, into a System Property
12866         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12867
12868         final Configuration configuration = new Configuration();
12869         Settings.System.getConfiguration(resolver, configuration);
12870         if (forceRtl) {
12871             // This will take care of setting the correct layout direction flags
12872             configuration.setLayoutDirection(configuration.locale);
12873         }
12874
12875         synchronized (this) {
12876             mDebugApp = mOrigDebugApp = debugApp;
12877             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12878             mAlwaysFinishActivities = alwaysFinishActivities;
12879             mLenientBackgroundCheck = lenientBackgroundCheck;
12880             mSupportsLeanbackOnly = supportsLeanbackOnly;
12881             mForceResizableActivities = forceResizable;
12882             mWindowManager.setForceResizableTasks(mForceResizableActivities);
12883             if (supportsMultiWindow || forceResizable) {
12884                 mSupportsMultiWindow = true;
12885                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12886                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12887             } else {
12888                 mSupportsMultiWindow = false;
12889                 mSupportsFreeformWindowManagement = false;
12890                 mSupportsPictureInPicture = false;
12891             }
12892             // This happens before any activities are started, so we can
12893             // change mConfiguration in-place.
12894             updateConfigurationLocked(configuration, null, true);
12895             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12896                     "Initial config: " + mConfiguration);
12897
12898             // Load resources only after the current configuration has been set.
12899             final Resources res = mContext.getResources();
12900             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12901             mThumbnailWidth = res.getDimensionPixelSize(
12902                     com.android.internal.R.dimen.thumbnail_width);
12903             mThumbnailHeight = res.getDimensionPixelSize(
12904                     com.android.internal.R.dimen.thumbnail_height);
12905             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12906                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
12907             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12908                     com.android.internal.R.string.config_appsNotReportingCrashes));
12909             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12910                 mFullscreenThumbnailScale = (float) res
12911                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12912                     (float) mConfiguration.screenWidthDp;
12913             } else {
12914                 mFullscreenThumbnailScale = res.getFraction(
12915                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12916             }
12917         }
12918     }
12919
12920     public boolean testIsSystemReady() {
12921         // no need to synchronize(this) just to read & return the value
12922         return mSystemReady;
12923     }
12924
12925     public void systemReady(final Runnable goingCallback) {
12926         synchronized(this) {
12927             if (mSystemReady) {
12928                 // If we're done calling all the receivers, run the next "boot phase" passed in
12929                 // by the SystemServer
12930                 if (goingCallback != null) {
12931                     goingCallback.run();
12932                 }
12933                 return;
12934             }
12935
12936             mLocalDeviceIdleController
12937                     = LocalServices.getService(DeviceIdleController.LocalService.class);
12938
12939             // Make sure we have the current profile info, since it is needed for security checks.
12940             mUserController.onSystemReady();
12941             mRecentTasks.onSystemReadyLocked();
12942             mAppOpsService.systemReady();
12943             mSystemReady = true;
12944         }
12945
12946         ArrayList<ProcessRecord> procsToKill = null;
12947         synchronized(mPidsSelfLocked) {
12948             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12949                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12950                 if (!isAllowedWhileBooting(proc.info)){
12951                     if (procsToKill == null) {
12952                         procsToKill = new ArrayList<ProcessRecord>();
12953                     }
12954                     procsToKill.add(proc);
12955                 }
12956             }
12957         }
12958
12959         synchronized(this) {
12960             if (procsToKill != null) {
12961                 for (int i=procsToKill.size()-1; i>=0; i--) {
12962                     ProcessRecord proc = procsToKill.get(i);
12963                     Slog.i(TAG, "Removing system update proc: " + proc);
12964                     removeProcessLocked(proc, true, false, "system update done");
12965                 }
12966             }
12967
12968             // Now that we have cleaned up any update processes, we
12969             // are ready to start launching real processes and know that
12970             // we won't trample on them any more.
12971             mProcessesReady = true;
12972         }
12973
12974         Slog.i(TAG, "System now ready");
12975         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12976             SystemClock.uptimeMillis());
12977
12978         synchronized(this) {
12979             // Make sure we have no pre-ready processes sitting around.
12980
12981             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12982                 ResolveInfo ri = mContext.getPackageManager()
12983                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12984                                 STOCK_PM_FLAGS);
12985                 CharSequence errorMsg = null;
12986                 if (ri != null) {
12987                     ActivityInfo ai = ri.activityInfo;
12988                     ApplicationInfo app = ai.applicationInfo;
12989                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12990                         mTopAction = Intent.ACTION_FACTORY_TEST;
12991                         mTopData = null;
12992                         mTopComponent = new ComponentName(app.packageName,
12993                                 ai.name);
12994                     } else {
12995                         errorMsg = mContext.getResources().getText(
12996                                 com.android.internal.R.string.factorytest_not_system);
12997                     }
12998                 } else {
12999                     errorMsg = mContext.getResources().getText(
13000                             com.android.internal.R.string.factorytest_no_action);
13001                 }
13002                 if (errorMsg != null) {
13003                     mTopAction = null;
13004                     mTopData = null;
13005                     mTopComponent = null;
13006                     Message msg = Message.obtain();
13007                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13008                     msg.getData().putCharSequence("msg", errorMsg);
13009                     mUiHandler.sendMessage(msg);
13010                 }
13011             }
13012         }
13013
13014         retrieveSettings();
13015         final int currentUserId;
13016         synchronized (this) {
13017             currentUserId = mUserController.getCurrentUserIdLocked();
13018             readGrantedUriPermissionsLocked();
13019         }
13020
13021         if (goingCallback != null) goingCallback.run();
13022
13023         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13024                 Integer.toString(currentUserId), currentUserId);
13025         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13026                 Integer.toString(currentUserId), currentUserId);
13027         mSystemServiceManager.startUser(currentUserId);
13028
13029         synchronized (this) {
13030             // Only start up encryption-aware persistent apps; once user is
13031             // unlocked we'll come back around and start unaware apps
13032             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13033
13034             // Start up initial activity.
13035             mBooting = true;
13036             // Enable home activity for system user, so that the system can always boot
13037             if (UserManager.isSplitSystemUser()) {
13038                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13039                 try {
13040                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13041                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13042                             UserHandle.USER_SYSTEM);
13043                 } catch (RemoteException e) {
13044                     throw e.rethrowAsRuntimeException();
13045                 }
13046             }
13047             startHomeActivityLocked(currentUserId, "systemReady");
13048
13049             try {
13050                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13051                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13052                             + " data partition or your device will be unstable.");
13053                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13054                 }
13055             } catch (RemoteException e) {
13056             }
13057
13058             if (!Build.isBuildConsistent()) {
13059                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13060                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13061             }
13062
13063             long ident = Binder.clearCallingIdentity();
13064             try {
13065                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13066                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13067                         | Intent.FLAG_RECEIVER_FOREGROUND);
13068                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13069                 broadcastIntentLocked(null, null, intent,
13070                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13071                         null, false, false, MY_PID, Process.SYSTEM_UID,
13072                         currentUserId);
13073                 intent = new Intent(Intent.ACTION_USER_STARTING);
13074                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13075                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13076                 broadcastIntentLocked(null, null, intent,
13077                         null, new IIntentReceiver.Stub() {
13078                             @Override
13079                             public void performReceive(Intent intent, int resultCode, String data,
13080                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13081                                     throws RemoteException {
13082                             }
13083                         }, 0, null, null,
13084                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13085                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13086             } catch (Throwable t) {
13087                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13088             } finally {
13089                 Binder.restoreCallingIdentity(ident);
13090             }
13091             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13092             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13093         }
13094     }
13095
13096     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13097         synchronized (this) {
13098             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13099         }
13100     }
13101
13102     void skipCurrentReceiverLocked(ProcessRecord app) {
13103         for (BroadcastQueue queue : mBroadcastQueues) {
13104             queue.skipCurrentReceiverLocked(app);
13105         }
13106     }
13107
13108     /**
13109      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13110      * The application process will exit immediately after this call returns.
13111      * @param app object of the crashing app, null for the system server
13112      * @param crashInfo describing the exception
13113      */
13114     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13115         ProcessRecord r = findAppProcess(app, "Crash");
13116         final String processName = app == null ? "system_server"
13117                 : (r == null ? "unknown" : r.processName);
13118
13119         handleApplicationCrashInner("crash", r, processName, crashInfo);
13120     }
13121
13122     /* Native crash reporting uses this inner version because it needs to be somewhat
13123      * decoupled from the AM-managed cleanup lifecycle
13124      */
13125     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13126             ApplicationErrorReport.CrashInfo crashInfo) {
13127         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13128                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13129                 r == null ? -1 : r.info.flags,
13130                 crashInfo.exceptionClassName,
13131                 crashInfo.exceptionMessage,
13132                 crashInfo.throwFileName,
13133                 crashInfo.throwLineNumber);
13134
13135         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13136
13137         mAppErrors.crashApplication(r, crashInfo);
13138     }
13139
13140     public void handleApplicationStrictModeViolation(
13141             IBinder app,
13142             int violationMask,
13143             StrictMode.ViolationInfo info) {
13144         ProcessRecord r = findAppProcess(app, "StrictMode");
13145         if (r == null) {
13146             return;
13147         }
13148
13149         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13150             Integer stackFingerprint = info.hashCode();
13151             boolean logIt = true;
13152             synchronized (mAlreadyLoggedViolatedStacks) {
13153                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13154                     logIt = false;
13155                     // TODO: sub-sample into EventLog for these, with
13156                     // the info.durationMillis?  Then we'd get
13157                     // the relative pain numbers, without logging all
13158                     // the stack traces repeatedly.  We'd want to do
13159                     // likewise in the client code, which also does
13160                     // dup suppression, before the Binder call.
13161                 } else {
13162                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13163                         mAlreadyLoggedViolatedStacks.clear();
13164                     }
13165                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13166                 }
13167             }
13168             if (logIt) {
13169                 logStrictModeViolationToDropBox(r, info);
13170             }
13171         }
13172
13173         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13174             AppErrorResult result = new AppErrorResult();
13175             synchronized (this) {
13176                 final long origId = Binder.clearCallingIdentity();
13177
13178                 Message msg = Message.obtain();
13179                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13180                 HashMap<String, Object> data = new HashMap<String, Object>();
13181                 data.put("result", result);
13182                 data.put("app", r);
13183                 data.put("violationMask", violationMask);
13184                 data.put("info", info);
13185                 msg.obj = data;
13186                 mUiHandler.sendMessage(msg);
13187
13188                 Binder.restoreCallingIdentity(origId);
13189             }
13190             int res = result.get();
13191             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13192         }
13193     }
13194
13195     // Depending on the policy in effect, there could be a bunch of
13196     // these in quick succession so we try to batch these together to
13197     // minimize disk writes, number of dropbox entries, and maximize
13198     // compression, by having more fewer, larger records.
13199     private void logStrictModeViolationToDropBox(
13200             ProcessRecord process,
13201             StrictMode.ViolationInfo info) {
13202         if (info == null) {
13203             return;
13204         }
13205         final boolean isSystemApp = process == null ||
13206                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13207                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13208         final String processName = process == null ? "unknown" : process.processName;
13209         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13210         final DropBoxManager dbox = (DropBoxManager)
13211                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13212
13213         // Exit early if the dropbox isn't configured to accept this report type.
13214         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13215
13216         boolean bufferWasEmpty;
13217         boolean needsFlush;
13218         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13219         synchronized (sb) {
13220             bufferWasEmpty = sb.length() == 0;
13221             appendDropBoxProcessHeaders(process, processName, sb);
13222             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13223             sb.append("System-App: ").append(isSystemApp).append("\n");
13224             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13225             if (info.violationNumThisLoop != 0) {
13226                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13227             }
13228             if (info.numAnimationsRunning != 0) {
13229                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13230             }
13231             if (info.broadcastIntentAction != null) {
13232                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13233             }
13234             if (info.durationMillis != -1) {
13235                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13236             }
13237             if (info.numInstances != -1) {
13238                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13239             }
13240             if (info.tags != null) {
13241                 for (String tag : info.tags) {
13242                     sb.append("Span-Tag: ").append(tag).append("\n");
13243                 }
13244             }
13245             sb.append("\n");
13246             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13247                 sb.append(info.crashInfo.stackTrace);
13248                 sb.append("\n");
13249             }
13250             if (info.message != null) {
13251                 sb.append(info.message);
13252                 sb.append("\n");
13253             }
13254
13255             // Only buffer up to ~64k.  Various logging bits truncate
13256             // things at 128k.
13257             needsFlush = (sb.length() > 64 * 1024);
13258         }
13259
13260         // Flush immediately if the buffer's grown too large, or this
13261         // is a non-system app.  Non-system apps are isolated with a
13262         // different tag & policy and not batched.
13263         //
13264         // Batching is useful during internal testing with
13265         // StrictMode settings turned up high.  Without batching,
13266         // thousands of separate files could be created on boot.
13267         if (!isSystemApp || needsFlush) {
13268             new Thread("Error dump: " + dropboxTag) {
13269                 @Override
13270                 public void run() {
13271                     String report;
13272                     synchronized (sb) {
13273                         report = sb.toString();
13274                         sb.delete(0, sb.length());
13275                         sb.trimToSize();
13276                     }
13277                     if (report.length() != 0) {
13278                         dbox.addText(dropboxTag, report);
13279                     }
13280                 }
13281             }.start();
13282             return;
13283         }
13284
13285         // System app batching:
13286         if (!bufferWasEmpty) {
13287             // An existing dropbox-writing thread is outstanding, so
13288             // we don't need to start it up.  The existing thread will
13289             // catch the buffer appends we just did.
13290             return;
13291         }
13292
13293         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13294         // (After this point, we shouldn't access AMS internal data structures.)
13295         new Thread("Error dump: " + dropboxTag) {
13296             @Override
13297             public void run() {
13298                 // 5 second sleep to let stacks arrive and be batched together
13299                 try {
13300                     Thread.sleep(5000);  // 5 seconds
13301                 } catch (InterruptedException e) {}
13302
13303                 String errorReport;
13304                 synchronized (mStrictModeBuffer) {
13305                     errorReport = mStrictModeBuffer.toString();
13306                     if (errorReport.length() == 0) {
13307                         return;
13308                     }
13309                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13310                     mStrictModeBuffer.trimToSize();
13311                 }
13312                 dbox.addText(dropboxTag, errorReport);
13313             }
13314         }.start();
13315     }
13316
13317     /**
13318      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13319      * @param app object of the crashing app, null for the system server
13320      * @param tag reported by the caller
13321      * @param system whether this wtf is coming from the system
13322      * @param crashInfo describing the context of the error
13323      * @return true if the process should exit immediately (WTF is fatal)
13324      */
13325     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13326             final ApplicationErrorReport.CrashInfo crashInfo) {
13327         final int callingUid = Binder.getCallingUid();
13328         final int callingPid = Binder.getCallingPid();
13329
13330         if (system) {
13331             // If this is coming from the system, we could very well have low-level
13332             // system locks held, so we want to do this all asynchronously.  And we
13333             // never want this to become fatal, so there is that too.
13334             mHandler.post(new Runnable() {
13335                 @Override public void run() {
13336                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13337                 }
13338             });
13339             return false;
13340         }
13341
13342         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13343                 crashInfo);
13344
13345         if (r != null && r.pid != Process.myPid() &&
13346                 Settings.Global.getInt(mContext.getContentResolver(),
13347                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13348             mAppErrors.crashApplication(r, crashInfo);
13349             return true;
13350         } else {
13351             return false;
13352         }
13353     }
13354
13355     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13356             final ApplicationErrorReport.CrashInfo crashInfo) {
13357         final ProcessRecord r = findAppProcess(app, "WTF");
13358         final String processName = app == null ? "system_server"
13359                 : (r == null ? "unknown" : r.processName);
13360
13361         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13362                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13363
13364         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13365
13366         return r;
13367     }
13368
13369     /**
13370      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13371      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13372      */
13373     private ProcessRecord findAppProcess(IBinder app, String reason) {
13374         if (app == null) {
13375             return null;
13376         }
13377
13378         synchronized (this) {
13379             final int NP = mProcessNames.getMap().size();
13380             for (int ip=0; ip<NP; ip++) {
13381                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13382                 final int NA = apps.size();
13383                 for (int ia=0; ia<NA; ia++) {
13384                     ProcessRecord p = apps.valueAt(ia);
13385                     if (p.thread != null && p.thread.asBinder() == app) {
13386                         return p;
13387                     }
13388                 }
13389             }
13390
13391             Slog.w(TAG, "Can't find mystery application for " + reason
13392                     + " from pid=" + Binder.getCallingPid()
13393                     + " uid=" + Binder.getCallingUid() + ": " + app);
13394             return null;
13395         }
13396     }
13397
13398     /**
13399      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13400      * to append various headers to the dropbox log text.
13401      */
13402     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13403             StringBuilder sb) {
13404         // Watchdog thread ends up invoking this function (with
13405         // a null ProcessRecord) to add the stack file to dropbox.
13406         // Do not acquire a lock on this (am) in such cases, as it
13407         // could cause a potential deadlock, if and when watchdog
13408         // is invoked due to unavailability of lock on am and it
13409         // would prevent watchdog from killing system_server.
13410         if (process == null) {
13411             sb.append("Process: ").append(processName).append("\n");
13412             return;
13413         }
13414         // Note: ProcessRecord 'process' is guarded by the service
13415         // instance.  (notably process.pkgList, which could otherwise change
13416         // concurrently during execution of this method)
13417         synchronized (this) {
13418             sb.append("Process: ").append(processName).append("\n");
13419             int flags = process.info.flags;
13420             IPackageManager pm = AppGlobals.getPackageManager();
13421             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13422             for (int ip=0; ip<process.pkgList.size(); ip++) {
13423                 String pkg = process.pkgList.keyAt(ip);
13424                 sb.append("Package: ").append(pkg);
13425                 try {
13426                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13427                     if (pi != null) {
13428                         sb.append(" v").append(pi.versionCode);
13429                         if (pi.versionName != null) {
13430                             sb.append(" (").append(pi.versionName).append(")");
13431                         }
13432                     }
13433                 } catch (RemoteException e) {
13434                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13435                 }
13436                 sb.append("\n");
13437             }
13438         }
13439     }
13440
13441     private static String processClass(ProcessRecord process) {
13442         if (process == null || process.pid == MY_PID) {
13443             return "system_server";
13444         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13445             return "system_app";
13446         } else {
13447             return "data_app";
13448         }
13449     }
13450
13451     private volatile long mWtfClusterStart;
13452     private volatile int mWtfClusterCount;
13453
13454     /**
13455      * Write a description of an error (crash, WTF, ANR) to the drop box.
13456      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13457      * @param process which caused the error, null means the system server
13458      * @param activity which triggered the error, null if unknown
13459      * @param parent activity related to the error, null if unknown
13460      * @param subject line related to the error, null if absent
13461      * @param report in long form describing the error, null if absent
13462      * @param logFile to include in the report, null if none
13463      * @param crashInfo giving an application stack trace, null if absent
13464      */
13465     public void addErrorToDropBox(String eventType,
13466             ProcessRecord process, String processName, ActivityRecord activity,
13467             ActivityRecord parent, String subject,
13468             final String report, final File logFile,
13469             final ApplicationErrorReport.CrashInfo crashInfo) {
13470         // NOTE -- this must never acquire the ActivityManagerService lock,
13471         // otherwise the watchdog may be prevented from resetting the system.
13472
13473         final String dropboxTag = processClass(process) + "_" + eventType;
13474         final DropBoxManager dbox = (DropBoxManager)
13475                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13476
13477         // Exit early if the dropbox isn't configured to accept this report type.
13478         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13479
13480         // Rate-limit how often we're willing to do the heavy lifting below to
13481         // collect and record logs; currently 5 logs per 10 second period.
13482         final long now = SystemClock.elapsedRealtime();
13483         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13484             mWtfClusterStart = now;
13485             mWtfClusterCount = 1;
13486         } else {
13487             if (mWtfClusterCount++ >= 5) return;
13488         }
13489
13490         final StringBuilder sb = new StringBuilder(1024);
13491         appendDropBoxProcessHeaders(process, processName, sb);
13492         if (process != null) {
13493             sb.append("Foreground: ")
13494                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13495                     .append("\n");
13496         }
13497         if (activity != null) {
13498             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13499         }
13500         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13501             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13502         }
13503         if (parent != null && parent != activity) {
13504             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13505         }
13506         if (subject != null) {
13507             sb.append("Subject: ").append(subject).append("\n");
13508         }
13509         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13510         if (Debug.isDebuggerConnected()) {
13511             sb.append("Debugger: Connected\n");
13512         }
13513         sb.append("\n");
13514
13515         // Do the rest in a worker thread to avoid blocking the caller on I/O
13516         // (After this point, we shouldn't access AMS internal data structures.)
13517         Thread worker = new Thread("Error dump: " + dropboxTag) {
13518             @Override
13519             public void run() {
13520                 if (report != null) {
13521                     sb.append(report);
13522                 }
13523                 if (logFile != null) {
13524                     try {
13525                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13526                                     "\n\n[[TRUNCATED]]"));
13527                     } catch (IOException e) {
13528                         Slog.e(TAG, "Error reading " + logFile, e);
13529                     }
13530                 }
13531                 if (crashInfo != null && crashInfo.stackTrace != null) {
13532                     sb.append(crashInfo.stackTrace);
13533                 }
13534
13535                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13536                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13537                 if (lines > 0) {
13538                     sb.append("\n");
13539
13540                     // Merge several logcat streams, and take the last N lines
13541                     InputStreamReader input = null;
13542                     try {
13543                         java.lang.Process logcat = new ProcessBuilder(
13544                                 "/system/bin/timeout", "-k", "15s", "10s",
13545                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13546                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13547                                         .redirectErrorStream(true).start();
13548
13549                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13550                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13551                         input = new InputStreamReader(logcat.getInputStream());
13552
13553                         int num;
13554                         char[] buf = new char[8192];
13555                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13556                     } catch (IOException e) {
13557                         Slog.e(TAG, "Error running logcat", e);
13558                     } finally {
13559                         if (input != null) try { input.close(); } catch (IOException e) {}
13560                     }
13561                 }
13562
13563                 dbox.addText(dropboxTag, sb.toString());
13564             }
13565         };
13566
13567         if (process == null) {
13568             // If process is null, we are being called from some internal code
13569             // and may be about to die -- run this synchronously.
13570             worker.run();
13571         } else {
13572             worker.start();
13573         }
13574     }
13575
13576     @Override
13577     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13578         enforceNotIsolatedCaller("getProcessesInErrorState");
13579         // assume our apps are happy - lazy create the list
13580         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13581
13582         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13583                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13584         int userId = UserHandle.getUserId(Binder.getCallingUid());
13585
13586         synchronized (this) {
13587
13588             // iterate across all processes
13589             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13590                 ProcessRecord app = mLruProcesses.get(i);
13591                 if (!allUsers && app.userId != userId) {
13592                     continue;
13593                 }
13594                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13595                     // This one's in trouble, so we'll generate a report for it
13596                     // crashes are higher priority (in case there's a crash *and* an anr)
13597                     ActivityManager.ProcessErrorStateInfo report = null;
13598                     if (app.crashing) {
13599                         report = app.crashingReport;
13600                     } else if (app.notResponding) {
13601                         report = app.notRespondingReport;
13602                     }
13603
13604                     if (report != null) {
13605                         if (errList == null) {
13606                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13607                         }
13608                         errList.add(report);
13609                     } else {
13610                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13611                                 " crashing = " + app.crashing +
13612                                 " notResponding = " + app.notResponding);
13613                     }
13614                 }
13615             }
13616         }
13617
13618         return errList;
13619     }
13620
13621     static int procStateToImportance(int procState, int memAdj,
13622             ActivityManager.RunningAppProcessInfo currApp) {
13623         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13624         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13625             currApp.lru = memAdj;
13626         } else {
13627             currApp.lru = 0;
13628         }
13629         return imp;
13630     }
13631
13632     private void fillInProcMemInfo(ProcessRecord app,
13633             ActivityManager.RunningAppProcessInfo outInfo) {
13634         outInfo.pid = app.pid;
13635         outInfo.uid = app.info.uid;
13636         if (mHeavyWeightProcess == app) {
13637             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13638         }
13639         if (app.persistent) {
13640             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13641         }
13642         if (app.activities.size() > 0) {
13643             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13644         }
13645         outInfo.lastTrimLevel = app.trimMemoryLevel;
13646         int adj = app.curAdj;
13647         int procState = app.curProcState;
13648         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13649         outInfo.importanceReasonCode = app.adjTypeCode;
13650         outInfo.processState = app.curProcState;
13651     }
13652
13653     @Override
13654     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13655         enforceNotIsolatedCaller("getRunningAppProcesses");
13656
13657         final int callingUid = Binder.getCallingUid();
13658
13659         // Lazy instantiation of list
13660         List<ActivityManager.RunningAppProcessInfo> runList = null;
13661         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13662                 callingUid) == PackageManager.PERMISSION_GRANTED;
13663         final int userId = UserHandle.getUserId(callingUid);
13664         final boolean allUids = isGetTasksAllowed(
13665                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13666
13667         synchronized (this) {
13668             // Iterate across all processes
13669             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13670                 ProcessRecord app = mLruProcesses.get(i);
13671                 if ((!allUsers && app.userId != userId)
13672                         || (!allUids && app.uid != callingUid)) {
13673                     continue;
13674                 }
13675                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13676                     // Generate process state info for running application
13677                     ActivityManager.RunningAppProcessInfo currApp =
13678                         new ActivityManager.RunningAppProcessInfo(app.processName,
13679                                 app.pid, app.getPackageList());
13680                     fillInProcMemInfo(app, currApp);
13681                     if (app.adjSource instanceof ProcessRecord) {
13682                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13683                         currApp.importanceReasonImportance =
13684                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13685                                         app.adjSourceProcState);
13686                     } else if (app.adjSource instanceof ActivityRecord) {
13687                         ActivityRecord r = (ActivityRecord)app.adjSource;
13688                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13689                     }
13690                     if (app.adjTarget instanceof ComponentName) {
13691                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13692                     }
13693                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13694                     //        + " lru=" + currApp.lru);
13695                     if (runList == null) {
13696                         runList = new ArrayList<>();
13697                     }
13698                     runList.add(currApp);
13699                 }
13700             }
13701         }
13702         return runList;
13703     }
13704
13705     @Override
13706     public List<ApplicationInfo> getRunningExternalApplications() {
13707         enforceNotIsolatedCaller("getRunningExternalApplications");
13708         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13709         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13710         if (runningApps != null && runningApps.size() > 0) {
13711             Set<String> extList = new HashSet<String>();
13712             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13713                 if (app.pkgList != null) {
13714                     for (String pkg : app.pkgList) {
13715                         extList.add(pkg);
13716                     }
13717                 }
13718             }
13719             IPackageManager pm = AppGlobals.getPackageManager();
13720             for (String pkg : extList) {
13721                 try {
13722                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13723                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13724                         retList.add(info);
13725                     }
13726                 } catch (RemoteException e) {
13727                 }
13728             }
13729         }
13730         return retList;
13731     }
13732
13733     @Override
13734     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13735         enforceNotIsolatedCaller("getMyMemoryState");
13736         synchronized (this) {
13737             ProcessRecord proc;
13738             synchronized (mPidsSelfLocked) {
13739                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13740             }
13741             fillInProcMemInfo(proc, outInfo);
13742         }
13743     }
13744
13745     @Override
13746     public int getMemoryTrimLevel() {
13747         enforceNotIsolatedCaller("getMyMemoryState");
13748         synchronized (this) {
13749             return mLastMemoryLevel;
13750         }
13751     }
13752
13753     @Override
13754     public void onShellCommand(FileDescriptor in, FileDescriptor out,
13755             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13756         (new ActivityManagerShellCommand(this, false)).exec(
13757                 this, in, out, err, args, resultReceiver);
13758     }
13759
13760     @Override
13761     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13762         if (checkCallingPermission(android.Manifest.permission.DUMP)
13763                 != PackageManager.PERMISSION_GRANTED) {
13764             pw.println("Permission Denial: can't dump ActivityManager from from pid="
13765                     + Binder.getCallingPid()
13766                     + ", uid=" + Binder.getCallingUid()
13767                     + " without permission "
13768                     + android.Manifest.permission.DUMP);
13769             return;
13770         }
13771
13772         boolean dumpAll = false;
13773         boolean dumpClient = false;
13774         String dumpPackage = null;
13775
13776         int opti = 0;
13777         while (opti < args.length) {
13778             String opt = args[opti];
13779             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13780                 break;
13781             }
13782             opti++;
13783             if ("-a".equals(opt)) {
13784                 dumpAll = true;
13785             } else if ("-c".equals(opt)) {
13786                 dumpClient = true;
13787             } else if ("-p".equals(opt)) {
13788                 if (opti < args.length) {
13789                     dumpPackage = args[opti];
13790                     opti++;
13791                 } else {
13792                     pw.println("Error: -p option requires package argument");
13793                     return;
13794                 }
13795                 dumpClient = true;
13796             } else if ("-h".equals(opt)) {
13797                 ActivityManagerShellCommand.dumpHelp(pw, true);
13798                 return;
13799             } else {
13800                 pw.println("Unknown argument: " + opt + "; use -h for help");
13801             }
13802         }
13803
13804         long origId = Binder.clearCallingIdentity();
13805         boolean more = false;
13806         // Is the caller requesting to dump a particular piece of data?
13807         if (opti < args.length) {
13808             String cmd = args[opti];
13809             opti++;
13810             if ("activities".equals(cmd) || "a".equals(cmd)) {
13811                 synchronized (this) {
13812                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13813                 }
13814             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13815                 synchronized (this) {
13816                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13817                 }
13818             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13819                 String[] newArgs;
13820                 String name;
13821                 if (opti >= args.length) {
13822                     name = null;
13823                     newArgs = EMPTY_STRING_ARRAY;
13824                 } else {
13825                     dumpPackage = args[opti];
13826                     opti++;
13827                     newArgs = new String[args.length - opti];
13828                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13829                             args.length - opti);
13830                 }
13831                 synchronized (this) {
13832                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13833                 }
13834             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13835                 String[] newArgs;
13836                 String name;
13837                 if (opti >= args.length) {
13838                     name = null;
13839                     newArgs = EMPTY_STRING_ARRAY;
13840                 } else {
13841                     dumpPackage = args[opti];
13842                     opti++;
13843                     newArgs = new String[args.length - opti];
13844                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13845                             args.length - opti);
13846                 }
13847                 synchronized (this) {
13848                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13849                 }
13850             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13851                 String[] newArgs;
13852                 String name;
13853                 if (opti >= args.length) {
13854                     name = null;
13855                     newArgs = EMPTY_STRING_ARRAY;
13856                 } else {
13857                     dumpPackage = args[opti];
13858                     opti++;
13859                     newArgs = new String[args.length - opti];
13860                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13861                             args.length - opti);
13862                 }
13863                 synchronized (this) {
13864                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13865                 }
13866             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13867                 synchronized (this) {
13868                     dumpOomLocked(fd, pw, args, opti, true);
13869                 }
13870             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13871                 synchronized (this) {
13872                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13873                 }
13874             } else if ("provider".equals(cmd)) {
13875                 String[] newArgs;
13876                 String name;
13877                 if (opti >= args.length) {
13878                     name = null;
13879                     newArgs = EMPTY_STRING_ARRAY;
13880                 } else {
13881                     name = args[opti];
13882                     opti++;
13883                     newArgs = new String[args.length - opti];
13884                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13885                 }
13886                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13887                     pw.println("No providers match: " + name);
13888                     pw.println("Use -h for help.");
13889                 }
13890             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13891                 synchronized (this) {
13892                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13893                 }
13894             } else if ("service".equals(cmd)) {
13895                 String[] newArgs;
13896                 String name;
13897                 if (opti >= args.length) {
13898                     name = null;
13899                     newArgs = EMPTY_STRING_ARRAY;
13900                 } else {
13901                     name = args[opti];
13902                     opti++;
13903                     newArgs = new String[args.length - opti];
13904                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13905                             args.length - opti);
13906                 }
13907                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13908                     pw.println("No services match: " + name);
13909                     pw.println("Use -h for help.");
13910                 }
13911             } else if ("package".equals(cmd)) {
13912                 String[] newArgs;
13913                 if (opti >= args.length) {
13914                     pw.println("package: no package name specified");
13915                     pw.println("Use -h for help.");
13916                 } else {
13917                     dumpPackage = args[opti];
13918                     opti++;
13919                     newArgs = new String[args.length - opti];
13920                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13921                             args.length - opti);
13922                     args = newArgs;
13923                     opti = 0;
13924                     more = true;
13925                 }
13926             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13927                 synchronized (this) {
13928                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13929                 }
13930             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13931                 if (dumpClient) {
13932                     ActiveServices.ServiceDumper dumper;
13933                     synchronized (this) {
13934                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13935                                 dumpPackage);
13936                     }
13937                     dumper.dumpWithClient();
13938                 } else {
13939                     synchronized (this) {
13940                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13941                                 dumpPackage).dumpLocked();
13942                     }
13943                 }
13944             } else if ("locks".equals(cmd)) {
13945                 LockGuard.dump(fd, pw, args);
13946             } else {
13947                 // Dumping a single activity?
13948                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13949                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13950                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13951                     if (res < 0) {
13952                         pw.println("Bad activity command, or no activities match: " + cmd);
13953                         pw.println("Use -h for help.");
13954                     }
13955                 }
13956             }
13957             if (!more) {
13958                 Binder.restoreCallingIdentity(origId);
13959                 return;
13960             }
13961         }
13962
13963         // No piece of data specified, dump everything.
13964         if (dumpClient) {
13965             ActiveServices.ServiceDumper sdumper;
13966             synchronized (this) {
13967                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13968                 pw.println();
13969                 if (dumpAll) {
13970                     pw.println("-------------------------------------------------------------------------------");
13971                 }
13972                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13973                 pw.println();
13974                 if (dumpAll) {
13975                     pw.println("-------------------------------------------------------------------------------");
13976                 }
13977                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13978                 pw.println();
13979                 if (dumpAll) {
13980                     pw.println("-------------------------------------------------------------------------------");
13981                 }
13982                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13983                 pw.println();
13984                 if (dumpAll) {
13985                     pw.println("-------------------------------------------------------------------------------");
13986                 }
13987                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13988                         dumpPackage);
13989             }
13990             sdumper.dumpWithClient();
13991             pw.println();
13992             synchronized (this) {
13993                 if (dumpAll) {
13994                     pw.println("-------------------------------------------------------------------------------");
13995                 }
13996                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13997                 pw.println();
13998                 if (dumpAll) {
13999                     pw.println("-------------------------------------------------------------------------------");
14000                 }
14001                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14002                 if (mAssociations.size() > 0) {
14003                     pw.println();
14004                     if (dumpAll) {
14005                         pw.println("-------------------------------------------------------------------------------");
14006                     }
14007                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14008                 }
14009                 pw.println();
14010                 if (dumpAll) {
14011                     pw.println("-------------------------------------------------------------------------------");
14012                 }
14013                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14014             }
14015
14016         } else {
14017             synchronized (this) {
14018                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14019                 pw.println();
14020                 if (dumpAll) {
14021                     pw.println("-------------------------------------------------------------------------------");
14022                 }
14023                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14024                 pw.println();
14025                 if (dumpAll) {
14026                     pw.println("-------------------------------------------------------------------------------");
14027                 }
14028                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14029                 pw.println();
14030                 if (dumpAll) {
14031                     pw.println("-------------------------------------------------------------------------------");
14032                 }
14033                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14034                 pw.println();
14035                 if (dumpAll) {
14036                     pw.println("-------------------------------------------------------------------------------");
14037                 }
14038                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14039                         .dumpLocked();
14040                 pw.println();
14041                 if (dumpAll) {
14042                     pw.println("-------------------------------------------------------------------------------");
14043                 }
14044                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14045                 pw.println();
14046                 if (dumpAll) {
14047                     pw.println("-------------------------------------------------------------------------------");
14048                 }
14049                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14050                 if (mAssociations.size() > 0) {
14051                     pw.println();
14052                     if (dumpAll) {
14053                         pw.println("-------------------------------------------------------------------------------");
14054                     }
14055                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14056                 }
14057                 pw.println();
14058                 if (dumpAll) {
14059                     pw.println("-------------------------------------------------------------------------------");
14060                 }
14061                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14062             }
14063         }
14064         Binder.restoreCallingIdentity(origId);
14065     }
14066
14067     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14068             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14069         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14070
14071         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14072                 dumpPackage);
14073         boolean needSep = printedAnything;
14074
14075         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14076                 dumpPackage, needSep, "  mFocusedActivity: ");
14077         if (printed) {
14078             printedAnything = true;
14079             needSep = false;
14080         }
14081
14082         if (dumpPackage == null) {
14083             if (needSep) {
14084                 pw.println();
14085             }
14086             needSep = true;
14087             printedAnything = true;
14088             mStackSupervisor.dump(pw, "  ");
14089         }
14090
14091         if (!printedAnything) {
14092             pw.println("  (nothing)");
14093         }
14094     }
14095
14096     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14097             int opti, boolean dumpAll, String dumpPackage) {
14098         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14099
14100         boolean printedAnything = false;
14101
14102         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14103             boolean printedHeader = false;
14104
14105             final int N = mRecentTasks.size();
14106             for (int i=0; i<N; i++) {
14107                 TaskRecord tr = mRecentTasks.get(i);
14108                 if (dumpPackage != null) {
14109                     if (tr.realActivity == null ||
14110                             !dumpPackage.equals(tr.realActivity)) {
14111                         continue;
14112                     }
14113                 }
14114                 if (!printedHeader) {
14115                     pw.println("  Recent tasks:");
14116                     printedHeader = true;
14117                     printedAnything = true;
14118                 }
14119                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14120                         pw.println(tr);
14121                 if (dumpAll) {
14122                     mRecentTasks.get(i).dump(pw, "    ");
14123                 }
14124             }
14125         }
14126
14127         if (!printedAnything) {
14128             pw.println("  (nothing)");
14129         }
14130     }
14131
14132     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14133             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14134         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14135
14136         int dumpUid = 0;
14137         if (dumpPackage != null) {
14138             IPackageManager pm = AppGlobals.getPackageManager();
14139             try {
14140                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14141             } catch (RemoteException e) {
14142             }
14143         }
14144
14145         boolean printedAnything = false;
14146
14147         final long now = SystemClock.uptimeMillis();
14148
14149         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14150             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14151                     = mAssociations.valueAt(i1);
14152             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14153                 SparseArray<ArrayMap<String, Association>> sourceUids
14154                         = targetComponents.valueAt(i2);
14155                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14156                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14157                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14158                         Association ass = sourceProcesses.valueAt(i4);
14159                         if (dumpPackage != null) {
14160                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14161                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14162                                 continue;
14163                             }
14164                         }
14165                         printedAnything = true;
14166                         pw.print("  ");
14167                         pw.print(ass.mTargetProcess);
14168                         pw.print("/");
14169                         UserHandle.formatUid(pw, ass.mTargetUid);
14170                         pw.print(" <- ");
14171                         pw.print(ass.mSourceProcess);
14172                         pw.print("/");
14173                         UserHandle.formatUid(pw, ass.mSourceUid);
14174                         pw.println();
14175                         pw.print("    via ");
14176                         pw.print(ass.mTargetComponent.flattenToShortString());
14177                         pw.println();
14178                         pw.print("    ");
14179                         long dur = ass.mTime;
14180                         if (ass.mNesting > 0) {
14181                             dur += now - ass.mStartTime;
14182                         }
14183                         TimeUtils.formatDuration(dur, pw);
14184                         pw.print(" (");
14185                         pw.print(ass.mCount);
14186                         pw.print(" times)");
14187                         pw.print("  ");
14188                         for (int i=0; i<ass.mStateTimes.length; i++) {
14189                             long amt = ass.mStateTimes[i];
14190                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14191                                 amt += now - ass.mLastStateUptime;
14192                             }
14193                             if (amt != 0) {
14194                                 pw.print(" ");
14195                                 pw.print(ProcessList.makeProcStateString(
14196                                             i + ActivityManager.MIN_PROCESS_STATE));
14197                                 pw.print("=");
14198                                 TimeUtils.formatDuration(amt, pw);
14199                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14200                                     pw.print("*");
14201                                 }
14202                             }
14203                         }
14204                         pw.println();
14205                         if (ass.mNesting > 0) {
14206                             pw.print("    Currently active: ");
14207                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14208                             pw.println();
14209                         }
14210                     }
14211                 }
14212             }
14213
14214         }
14215
14216         if (!printedAnything) {
14217             pw.println("  (nothing)");
14218         }
14219     }
14220
14221     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14222             String header, boolean needSep) {
14223         boolean printed = false;
14224         int whichAppId = -1;
14225         if (dumpPackage != null) {
14226             try {
14227                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14228                         dumpPackage, 0);
14229                 whichAppId = UserHandle.getAppId(info.uid);
14230             } catch (NameNotFoundException e) {
14231                 e.printStackTrace();
14232             }
14233         }
14234         for (int i=0; i<uids.size(); i++) {
14235             UidRecord uidRec = uids.valueAt(i);
14236             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14237                 continue;
14238             }
14239             if (!printed) {
14240                 printed = true;
14241                 if (needSep) {
14242                     pw.println();
14243                 }
14244                 pw.print("  ");
14245                 pw.println(header);
14246                 needSep = true;
14247             }
14248             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14249             pw.print(": "); pw.println(uidRec);
14250         }
14251         return printed;
14252     }
14253
14254     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14255             int opti, boolean dumpAll, String dumpPackage) {
14256         boolean needSep = false;
14257         boolean printedAnything = false;
14258         int numPers = 0;
14259
14260         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14261
14262         if (dumpAll) {
14263             final int NP = mProcessNames.getMap().size();
14264             for (int ip=0; ip<NP; ip++) {
14265                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14266                 final int NA = procs.size();
14267                 for (int ia=0; ia<NA; ia++) {
14268                     ProcessRecord r = procs.valueAt(ia);
14269                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14270                         continue;
14271                     }
14272                     if (!needSep) {
14273                         pw.println("  All known processes:");
14274                         needSep = true;
14275                         printedAnything = true;
14276                     }
14277                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14278                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14279                         pw.print(" "); pw.println(r);
14280                     r.dump(pw, "    ");
14281                     if (r.persistent) {
14282                         numPers++;
14283                     }
14284                 }
14285             }
14286         }
14287
14288         if (mIsolatedProcesses.size() > 0) {
14289             boolean printed = false;
14290             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14291                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14292                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14293                     continue;
14294                 }
14295                 if (!printed) {
14296                     if (needSep) {
14297                         pw.println();
14298                     }
14299                     pw.println("  Isolated process list (sorted by uid):");
14300                     printedAnything = true;
14301                     printed = true;
14302                     needSep = true;
14303                 }
14304                 pw.println(String.format("%sIsolated #%2d: %s",
14305                         "    ", i, r.toString()));
14306             }
14307         }
14308
14309         if (mActiveUids.size() > 0) {
14310             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14311                 printedAnything = needSep = true;
14312             }
14313         }
14314         if (mValidateUids.size() > 0) {
14315             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14316                 printedAnything = needSep = true;
14317             }
14318         }
14319
14320         if (mLruProcesses.size() > 0) {
14321             if (needSep) {
14322                 pw.println();
14323             }
14324             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14325                     pw.print(" total, non-act at ");
14326                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14327                     pw.print(", non-svc at ");
14328                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14329                     pw.println("):");
14330             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14331             needSep = true;
14332             printedAnything = true;
14333         }
14334
14335         if (dumpAll || dumpPackage != null) {
14336             synchronized (mPidsSelfLocked) {
14337                 boolean printed = false;
14338                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14339                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14340                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14341                         continue;
14342                     }
14343                     if (!printed) {
14344                         if (needSep) pw.println();
14345                         needSep = true;
14346                         pw.println("  PID mappings:");
14347                         printed = true;
14348                         printedAnything = true;
14349                     }
14350                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14351                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14352                 }
14353             }
14354         }
14355
14356         if (mForegroundProcesses.size() > 0) {
14357             synchronized (mPidsSelfLocked) {
14358                 boolean printed = false;
14359                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14360                     ProcessRecord r = mPidsSelfLocked.get(
14361                             mForegroundProcesses.valueAt(i).pid);
14362                     if (dumpPackage != null && (r == null
14363                             || !r.pkgList.containsKey(dumpPackage))) {
14364                         continue;
14365                     }
14366                     if (!printed) {
14367                         if (needSep) pw.println();
14368                         needSep = true;
14369                         pw.println("  Foreground Processes:");
14370                         printed = true;
14371                         printedAnything = true;
14372                     }
14373                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14374                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14375                 }
14376             }
14377         }
14378
14379         if (mPersistentStartingProcesses.size() > 0) {
14380             if (needSep) pw.println();
14381             needSep = true;
14382             printedAnything = true;
14383             pw.println("  Persisent processes that are starting:");
14384             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14385                     "Starting Norm", "Restarting PERS", dumpPackage);
14386         }
14387
14388         if (mRemovedProcesses.size() > 0) {
14389             if (needSep) pw.println();
14390             needSep = true;
14391             printedAnything = true;
14392             pw.println("  Processes that are being removed:");
14393             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14394                     "Removed Norm", "Removed PERS", dumpPackage);
14395         }
14396
14397         if (mProcessesOnHold.size() > 0) {
14398             if (needSep) pw.println();
14399             needSep = true;
14400             printedAnything = true;
14401             pw.println("  Processes that are on old until the system is ready:");
14402             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14403                     "OnHold Norm", "OnHold PERS", dumpPackage);
14404         }
14405
14406         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14407
14408         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14409         if (needSep) {
14410             printedAnything = true;
14411         }
14412
14413         if (dumpPackage == null) {
14414             pw.println();
14415             needSep = false;
14416             mUserController.dump(pw, dumpAll);
14417         }
14418         if (mHomeProcess != null && (dumpPackage == null
14419                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14420             if (needSep) {
14421                 pw.println();
14422                 needSep = false;
14423             }
14424             pw.println("  mHomeProcess: " + mHomeProcess);
14425         }
14426         if (mPreviousProcess != null && (dumpPackage == null
14427                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14428             if (needSep) {
14429                 pw.println();
14430                 needSep = false;
14431             }
14432             pw.println("  mPreviousProcess: " + mPreviousProcess);
14433         }
14434         if (dumpAll) {
14435             StringBuilder sb = new StringBuilder(128);
14436             sb.append("  mPreviousProcessVisibleTime: ");
14437             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14438             pw.println(sb);
14439         }
14440         if (mHeavyWeightProcess != null && (dumpPackage == null
14441                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14442             if (needSep) {
14443                 pw.println();
14444                 needSep = false;
14445             }
14446             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14447         }
14448         if (dumpPackage == null) {
14449             pw.println("  mConfiguration: " + mConfiguration);
14450         }
14451         if (dumpAll) {
14452             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14453             if (mCompatModePackages.getPackages().size() > 0) {
14454                 boolean printed = false;
14455                 for (Map.Entry<String, Integer> entry
14456                         : mCompatModePackages.getPackages().entrySet()) {
14457                     String pkg = entry.getKey();
14458                     int mode = entry.getValue();
14459                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14460                         continue;
14461                     }
14462                     if (!printed) {
14463                         pw.println("  mScreenCompatPackages:");
14464                         printed = true;
14465                     }
14466                     pw.print("    "); pw.print(pkg); pw.print(": ");
14467                             pw.print(mode); pw.println();
14468                 }
14469             }
14470         }
14471         if (dumpPackage == null) {
14472             pw.println("  mWakefulness="
14473                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14474             pw.println("  mSleepTokens=" + mSleepTokens);
14475             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14476                     + lockScreenShownToString());
14477             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14478             if (mRunningVoice != null) {
14479                 pw.println("  mRunningVoice=" + mRunningVoice);
14480                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14481             }
14482         }
14483         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14484                 || mOrigWaitForDebugger) {
14485             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14486                     || dumpPackage.equals(mOrigDebugApp)) {
14487                 if (needSep) {
14488                     pw.println();
14489                     needSep = false;
14490                 }
14491                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14492                         + " mDebugTransient=" + mDebugTransient
14493                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14494             }
14495         }
14496         if (mCurAppTimeTracker != null) {
14497             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14498         }
14499         if (mMemWatchProcesses.getMap().size() > 0) {
14500             pw.println("  Mem watch processes:");
14501             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14502                     = mMemWatchProcesses.getMap();
14503             for (int i=0; i<procs.size(); i++) {
14504                 final String proc = procs.keyAt(i);
14505                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14506                 for (int j=0; j<uids.size(); j++) {
14507                     if (needSep) {
14508                         pw.println();
14509                         needSep = false;
14510                     }
14511                     StringBuilder sb = new StringBuilder();
14512                     sb.append("    ").append(proc).append('/');
14513                     UserHandle.formatUid(sb, uids.keyAt(j));
14514                     Pair<Long, String> val = uids.valueAt(j);
14515                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14516                     if (val.second != null) {
14517                         sb.append(", report to ").append(val.second);
14518                     }
14519                     pw.println(sb.toString());
14520                 }
14521             }
14522             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14523             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14524             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14525                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14526         }
14527         if (mTrackAllocationApp != null) {
14528             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14529                 if (needSep) {
14530                     pw.println();
14531                     needSep = false;
14532                 }
14533                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14534             }
14535         }
14536         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14537                 || mProfileFd != null) {
14538             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14539                 if (needSep) {
14540                     pw.println();
14541                     needSep = false;
14542                 }
14543                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14544                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14545                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14546                         + mAutoStopProfiler);
14547                 pw.println("  mProfileType=" + mProfileType);
14548             }
14549         }
14550         if (mNativeDebuggingApp != null) {
14551             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14552                 if (needSep) {
14553                     pw.println();
14554                     needSep = false;
14555                 }
14556                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14557             }
14558         }
14559         if (dumpPackage == null) {
14560             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14561                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14562                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14563             }
14564             if (mController != null) {
14565                 pw.println("  mController=" + mController
14566                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14567             }
14568             if (dumpAll) {
14569                 pw.println("  Total persistent processes: " + numPers);
14570                 pw.println("  mProcessesReady=" + mProcessesReady
14571                         + " mSystemReady=" + mSystemReady
14572                         + " mBooted=" + mBooted
14573                         + " mFactoryTest=" + mFactoryTest);
14574                 pw.println("  mBooting=" + mBooting
14575                         + " mCallFinishBooting=" + mCallFinishBooting
14576                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14577                 pw.print("  mLastPowerCheckRealtime=");
14578                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14579                         pw.println("");
14580                 pw.print("  mLastPowerCheckUptime=");
14581                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14582                         pw.println("");
14583                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14584                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14585                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14586                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14587                         + " (" + mLruProcesses.size() + " total)"
14588                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14589                         + " mNumServiceProcs=" + mNumServiceProcs
14590                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14591                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14592                         + " mLastMemoryLevel=" + mLastMemoryLevel
14593                         + " mLastNumProcesses=" + mLastNumProcesses);
14594                 long now = SystemClock.uptimeMillis();
14595                 pw.print("  mLastIdleTime=");
14596                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14597                         pw.print(" mLowRamSinceLastIdle=");
14598                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14599                         pw.println();
14600             }
14601         }
14602
14603         if (!printedAnything) {
14604             pw.println("  (nothing)");
14605         }
14606     }
14607
14608     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14609             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14610         if (mProcessesToGc.size() > 0) {
14611             boolean printed = false;
14612             long now = SystemClock.uptimeMillis();
14613             for (int i=0; i<mProcessesToGc.size(); i++) {
14614                 ProcessRecord proc = mProcessesToGc.get(i);
14615                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14616                     continue;
14617                 }
14618                 if (!printed) {
14619                     if (needSep) pw.println();
14620                     needSep = true;
14621                     pw.println("  Processes that are waiting to GC:");
14622                     printed = true;
14623                 }
14624                 pw.print("    Process "); pw.println(proc);
14625                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14626                         pw.print(", last gced=");
14627                         pw.print(now-proc.lastRequestedGc);
14628                         pw.print(" ms ago, last lowMem=");
14629                         pw.print(now-proc.lastLowMemory);
14630                         pw.println(" ms ago");
14631
14632             }
14633         }
14634         return needSep;
14635     }
14636
14637     void printOomLevel(PrintWriter pw, String name, int adj) {
14638         pw.print("    ");
14639         if (adj >= 0) {
14640             pw.print(' ');
14641             if (adj < 10) pw.print(' ');
14642         } else {
14643             if (adj > -10) pw.print(' ');
14644         }
14645         pw.print(adj);
14646         pw.print(": ");
14647         pw.print(name);
14648         pw.print(" (");
14649         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14650         pw.println(")");
14651     }
14652
14653     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14654             int opti, boolean dumpAll) {
14655         boolean needSep = false;
14656
14657         if (mLruProcesses.size() > 0) {
14658             if (needSep) pw.println();
14659             needSep = true;
14660             pw.println("  OOM levels:");
14661             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14662             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14663             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14664             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14665             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14666             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14667             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14668             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14669             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14670             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14671             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14672             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14673             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14674             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14675
14676             if (needSep) pw.println();
14677             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14678                     pw.print(" total, non-act at ");
14679                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14680                     pw.print(", non-svc at ");
14681                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14682                     pw.println("):");
14683             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14684             needSep = true;
14685         }
14686
14687         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14688
14689         pw.println();
14690         pw.println("  mHomeProcess: " + mHomeProcess);
14691         pw.println("  mPreviousProcess: " + mPreviousProcess);
14692         if (mHeavyWeightProcess != null) {
14693             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14694         }
14695
14696         return true;
14697     }
14698
14699     /**
14700      * There are three ways to call this:
14701      *  - no provider specified: dump all the providers
14702      *  - a flattened component name that matched an existing provider was specified as the
14703      *    first arg: dump that one provider
14704      *  - the first arg isn't the flattened component name of an existing provider:
14705      *    dump all providers whose component contains the first arg as a substring
14706      */
14707     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14708             int opti, boolean dumpAll) {
14709         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14710     }
14711
14712     static class ItemMatcher {
14713         ArrayList<ComponentName> components;
14714         ArrayList<String> strings;
14715         ArrayList<Integer> objects;
14716         boolean all;
14717
14718         ItemMatcher() {
14719             all = true;
14720         }
14721
14722         void build(String name) {
14723             ComponentName componentName = ComponentName.unflattenFromString(name);
14724             if (componentName != null) {
14725                 if (components == null) {
14726                     components = new ArrayList<ComponentName>();
14727                 }
14728                 components.add(componentName);
14729                 all = false;
14730             } else {
14731                 int objectId = 0;
14732                 // Not a '/' separated full component name; maybe an object ID?
14733                 try {
14734                     objectId = Integer.parseInt(name, 16);
14735                     if (objects == null) {
14736                         objects = new ArrayList<Integer>();
14737                     }
14738                     objects.add(objectId);
14739                     all = false;
14740                 } catch (RuntimeException e) {
14741                     // Not an integer; just do string match.
14742                     if (strings == null) {
14743                         strings = new ArrayList<String>();
14744                     }
14745                     strings.add(name);
14746                     all = false;
14747                 }
14748             }
14749         }
14750
14751         int build(String[] args, int opti) {
14752             for (; opti<args.length; opti++) {
14753                 String name = args[opti];
14754                 if ("--".equals(name)) {
14755                     return opti+1;
14756                 }
14757                 build(name);
14758             }
14759             return opti;
14760         }
14761
14762         boolean match(Object object, ComponentName comp) {
14763             if (all) {
14764                 return true;
14765             }
14766             if (components != null) {
14767                 for (int i=0; i<components.size(); i++) {
14768                     if (components.get(i).equals(comp)) {
14769                         return true;
14770                     }
14771                 }
14772             }
14773             if (objects != null) {
14774                 for (int i=0; i<objects.size(); i++) {
14775                     if (System.identityHashCode(object) == objects.get(i)) {
14776                         return true;
14777                     }
14778                 }
14779             }
14780             if (strings != null) {
14781                 String flat = comp.flattenToString();
14782                 for (int i=0; i<strings.size(); i++) {
14783                     if (flat.contains(strings.get(i))) {
14784                         return true;
14785                     }
14786                 }
14787             }
14788             return false;
14789         }
14790     }
14791
14792     /**
14793      * There are three things that cmd can be:
14794      *  - a flattened component name that matches an existing activity
14795      *  - the cmd arg isn't the flattened component name of an existing activity:
14796      *    dump all activity whose component contains the cmd as a substring
14797      *  - A hex number of the ActivityRecord object instance.
14798      */
14799     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14800             int opti, boolean dumpAll) {
14801         ArrayList<ActivityRecord> activities;
14802
14803         synchronized (this) {
14804             activities = mStackSupervisor.getDumpActivitiesLocked(name);
14805         }
14806
14807         if (activities.size() <= 0) {
14808             return false;
14809         }
14810
14811         String[] newArgs = new String[args.length - opti];
14812         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14813
14814         TaskRecord lastTask = null;
14815         boolean needSep = false;
14816         for (int i=activities.size()-1; i>=0; i--) {
14817             ActivityRecord r = activities.get(i);
14818             if (needSep) {
14819                 pw.println();
14820             }
14821             needSep = true;
14822             synchronized (this) {
14823                 if (lastTask != r.task) {
14824                     lastTask = r.task;
14825                     pw.print("TASK "); pw.print(lastTask.affinity);
14826                             pw.print(" id="); pw.println(lastTask.taskId);
14827                     if (dumpAll) {
14828                         lastTask.dump(pw, "  ");
14829                     }
14830                 }
14831             }
14832             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14833         }
14834         return true;
14835     }
14836
14837     /**
14838      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14839      * there is a thread associated with the activity.
14840      */
14841     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14842             final ActivityRecord r, String[] args, boolean dumpAll) {
14843         String innerPrefix = prefix + "  ";
14844         synchronized (this) {
14845             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14846                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14847                     pw.print(" pid=");
14848                     if (r.app != null) pw.println(r.app.pid);
14849                     else pw.println("(not running)");
14850             if (dumpAll) {
14851                 r.dump(pw, innerPrefix);
14852             }
14853         }
14854         if (r.app != null && r.app.thread != null) {
14855             // flush anything that is already in the PrintWriter since the thread is going
14856             // to write to the file descriptor directly
14857             pw.flush();
14858             try {
14859                 TransferPipe tp = new TransferPipe();
14860                 try {
14861                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14862                             r.appToken, innerPrefix, args);
14863                     tp.go(fd);
14864                 } finally {
14865                     tp.kill();
14866                 }
14867             } catch (IOException e) {
14868                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14869             } catch (RemoteException e) {
14870                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14871             }
14872         }
14873     }
14874
14875     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14876             int opti, boolean dumpAll, String dumpPackage) {
14877         boolean needSep = false;
14878         boolean onlyHistory = false;
14879         boolean printedAnything = false;
14880
14881         if ("history".equals(dumpPackage)) {
14882             if (opti < args.length && "-s".equals(args[opti])) {
14883                 dumpAll = false;
14884             }
14885             onlyHistory = true;
14886             dumpPackage = null;
14887         }
14888
14889         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14890         if (!onlyHistory && dumpAll) {
14891             if (mRegisteredReceivers.size() > 0) {
14892                 boolean printed = false;
14893                 Iterator it = mRegisteredReceivers.values().iterator();
14894                 while (it.hasNext()) {
14895                     ReceiverList r = (ReceiverList)it.next();
14896                     if (dumpPackage != null && (r.app == null ||
14897                             !dumpPackage.equals(r.app.info.packageName))) {
14898                         continue;
14899                     }
14900                     if (!printed) {
14901                         pw.println("  Registered Receivers:");
14902                         needSep = true;
14903                         printed = true;
14904                         printedAnything = true;
14905                     }
14906                     pw.print("  * "); pw.println(r);
14907                     r.dump(pw, "    ");
14908                 }
14909             }
14910
14911             if (mReceiverResolver.dump(pw, needSep ?
14912                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14913                     "    ", dumpPackage, false, false)) {
14914                 needSep = true;
14915                 printedAnything = true;
14916             }
14917         }
14918
14919         for (BroadcastQueue q : mBroadcastQueues) {
14920             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14921             printedAnything |= needSep;
14922         }
14923
14924         needSep = true;
14925
14926         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14927             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14928                 if (needSep) {
14929                     pw.println();
14930                 }
14931                 needSep = true;
14932                 printedAnything = true;
14933                 pw.print("  Sticky broadcasts for user ");
14934                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14935                 StringBuilder sb = new StringBuilder(128);
14936                 for (Map.Entry<String, ArrayList<Intent>> ent
14937                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14938                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14939                     if (dumpAll) {
14940                         pw.println(":");
14941                         ArrayList<Intent> intents = ent.getValue();
14942                         final int N = intents.size();
14943                         for (int i=0; i<N; i++) {
14944                             sb.setLength(0);
14945                             sb.append("    Intent: ");
14946                             intents.get(i).toShortString(sb, false, true, false, false);
14947                             pw.println(sb.toString());
14948                             Bundle bundle = intents.get(i).getExtras();
14949                             if (bundle != null) {
14950                                 pw.print("      ");
14951                                 pw.println(bundle.toString());
14952                             }
14953                         }
14954                     } else {
14955                         pw.println("");
14956                     }
14957                 }
14958             }
14959         }
14960
14961         if (!onlyHistory && dumpAll) {
14962             pw.println();
14963             for (BroadcastQueue queue : mBroadcastQueues) {
14964                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14965                         + queue.mBroadcastsScheduled);
14966             }
14967             pw.println("  mHandler:");
14968             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14969             needSep = true;
14970             printedAnything = true;
14971         }
14972
14973         if (!printedAnything) {
14974             pw.println("  (nothing)");
14975         }
14976     }
14977
14978     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14979             int opti, boolean dumpAll, String dumpPackage) {
14980         boolean needSep;
14981         boolean printedAnything = false;
14982
14983         ItemMatcher matcher = new ItemMatcher();
14984         matcher.build(args, opti);
14985
14986         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14987
14988         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14989         printedAnything |= needSep;
14990
14991         if (mLaunchingProviders.size() > 0) {
14992             boolean printed = false;
14993             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14994                 ContentProviderRecord r = mLaunchingProviders.get(i);
14995                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14996                     continue;
14997                 }
14998                 if (!printed) {
14999                     if (needSep) pw.println();
15000                     needSep = true;
15001                     pw.println("  Launching content providers:");
15002                     printed = true;
15003                     printedAnything = true;
15004                 }
15005                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15006                         pw.println(r);
15007             }
15008         }
15009
15010         if (!printedAnything) {
15011             pw.println("  (nothing)");
15012         }
15013     }
15014
15015     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15016             int opti, boolean dumpAll, String dumpPackage) {
15017         boolean needSep = false;
15018         boolean printedAnything = false;
15019
15020         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15021
15022         if (mGrantedUriPermissions.size() > 0) {
15023             boolean printed = false;
15024             int dumpUid = -2;
15025             if (dumpPackage != null) {
15026                 try {
15027                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15028                             MATCH_UNINSTALLED_PACKAGES, 0);
15029                 } catch (NameNotFoundException e) {
15030                     dumpUid = -1;
15031                 }
15032             }
15033             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15034                 int uid = mGrantedUriPermissions.keyAt(i);
15035                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15036                     continue;
15037                 }
15038                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15039                 if (!printed) {
15040                     if (needSep) pw.println();
15041                     needSep = true;
15042                     pw.println("  Granted Uri Permissions:");
15043                     printed = true;
15044                     printedAnything = true;
15045                 }
15046                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15047                 for (UriPermission perm : perms.values()) {
15048                     pw.print("    "); pw.println(perm);
15049                     if (dumpAll) {
15050                         perm.dump(pw, "      ");
15051                     }
15052                 }
15053             }
15054         }
15055
15056         if (!printedAnything) {
15057             pw.println("  (nothing)");
15058         }
15059     }
15060
15061     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15062             int opti, boolean dumpAll, String dumpPackage) {
15063         boolean printed = false;
15064
15065         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15066
15067         if (mIntentSenderRecords.size() > 0) {
15068             Iterator<WeakReference<PendingIntentRecord>> it
15069                     = mIntentSenderRecords.values().iterator();
15070             while (it.hasNext()) {
15071                 WeakReference<PendingIntentRecord> ref = it.next();
15072                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15073                 if (dumpPackage != null && (rec == null
15074                         || !dumpPackage.equals(rec.key.packageName))) {
15075                     continue;
15076                 }
15077                 printed = true;
15078                 if (rec != null) {
15079                     pw.print("  * "); pw.println(rec);
15080                     if (dumpAll) {
15081                         rec.dump(pw, "    ");
15082                     }
15083                 } else {
15084                     pw.print("  * "); pw.println(ref);
15085                 }
15086             }
15087         }
15088
15089         if (!printed) {
15090             pw.println("  (nothing)");
15091         }
15092     }
15093
15094     private static final int dumpProcessList(PrintWriter pw,
15095             ActivityManagerService service, List list,
15096             String prefix, String normalLabel, String persistentLabel,
15097             String dumpPackage) {
15098         int numPers = 0;
15099         final int N = list.size()-1;
15100         for (int i=N; i>=0; i--) {
15101             ProcessRecord r = (ProcessRecord)list.get(i);
15102             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15103                 continue;
15104             }
15105             pw.println(String.format("%s%s #%2d: %s",
15106                     prefix, (r.persistent ? persistentLabel : normalLabel),
15107                     i, r.toString()));
15108             if (r.persistent) {
15109                 numPers++;
15110             }
15111         }
15112         return numPers;
15113     }
15114
15115     private static final boolean dumpProcessOomList(PrintWriter pw,
15116             ActivityManagerService service, List<ProcessRecord> origList,
15117             String prefix, String normalLabel, String persistentLabel,
15118             boolean inclDetails, String dumpPackage) {
15119
15120         ArrayList<Pair<ProcessRecord, Integer>> list
15121                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15122         for (int i=0; i<origList.size(); i++) {
15123             ProcessRecord r = origList.get(i);
15124             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15125                 continue;
15126             }
15127             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15128         }
15129
15130         if (list.size() <= 0) {
15131             return false;
15132         }
15133
15134         Comparator<Pair<ProcessRecord, Integer>> comparator
15135                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15136             @Override
15137             public int compare(Pair<ProcessRecord, Integer> object1,
15138                     Pair<ProcessRecord, Integer> object2) {
15139                 if (object1.first.setAdj != object2.first.setAdj) {
15140                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15141                 }
15142                 if (object1.first.setProcState != object2.first.setProcState) {
15143                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15144                 }
15145                 if (object1.second.intValue() != object2.second.intValue()) {
15146                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15147                 }
15148                 return 0;
15149             }
15150         };
15151
15152         Collections.sort(list, comparator);
15153
15154         final long curRealtime = SystemClock.elapsedRealtime();
15155         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15156         final long curUptime = SystemClock.uptimeMillis();
15157         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15158
15159         for (int i=list.size()-1; i>=0; i--) {
15160             ProcessRecord r = list.get(i).first;
15161             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15162             char schedGroup;
15163             switch (r.setSchedGroup) {
15164                 case ProcessList.SCHED_GROUP_BACKGROUND:
15165                     schedGroup = 'B';
15166                     break;
15167                 case ProcessList.SCHED_GROUP_DEFAULT:
15168                     schedGroup = 'F';
15169                     break;
15170                 case ProcessList.SCHED_GROUP_TOP_APP:
15171                     schedGroup = 'T';
15172                     break;
15173                 default:
15174                     schedGroup = '?';
15175                     break;
15176             }
15177             char foreground;
15178             if (r.foregroundActivities) {
15179                 foreground = 'A';
15180             } else if (r.foregroundServices) {
15181                 foreground = 'S';
15182             } else {
15183                 foreground = ' ';
15184             }
15185             String procState = ProcessList.makeProcStateString(r.curProcState);
15186             pw.print(prefix);
15187             pw.print(r.persistent ? persistentLabel : normalLabel);
15188             pw.print(" #");
15189             int num = (origList.size()-1)-list.get(i).second;
15190             if (num < 10) pw.print(' ');
15191             pw.print(num);
15192             pw.print(": ");
15193             pw.print(oomAdj);
15194             pw.print(' ');
15195             pw.print(schedGroup);
15196             pw.print('/');
15197             pw.print(foreground);
15198             pw.print('/');
15199             pw.print(procState);
15200             pw.print(" trm:");
15201             if (r.trimMemoryLevel < 10) pw.print(' ');
15202             pw.print(r.trimMemoryLevel);
15203             pw.print(' ');
15204             pw.print(r.toShortString());
15205             pw.print(" (");
15206             pw.print(r.adjType);
15207             pw.println(')');
15208             if (r.adjSource != null || r.adjTarget != null) {
15209                 pw.print(prefix);
15210                 pw.print("    ");
15211                 if (r.adjTarget instanceof ComponentName) {
15212                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15213                 } else if (r.adjTarget != null) {
15214                     pw.print(r.adjTarget.toString());
15215                 } else {
15216                     pw.print("{null}");
15217                 }
15218                 pw.print("<=");
15219                 if (r.adjSource instanceof ProcessRecord) {
15220                     pw.print("Proc{");
15221                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15222                     pw.println("}");
15223                 } else if (r.adjSource != null) {
15224                     pw.println(r.adjSource.toString());
15225                 } else {
15226                     pw.println("{null}");
15227                 }
15228             }
15229             if (inclDetails) {
15230                 pw.print(prefix);
15231                 pw.print("    ");
15232                 pw.print("oom: max="); pw.print(r.maxAdj);
15233                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15234                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15235                 pw.print(" cur="); pw.print(r.curAdj);
15236                 pw.print(" set="); pw.println(r.setAdj);
15237                 pw.print(prefix);
15238                 pw.print("    ");
15239                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15240                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15241                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15242                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15243                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15244                 pw.println();
15245                 pw.print(prefix);
15246                 pw.print("    ");
15247                 pw.print("cached="); pw.print(r.cached);
15248                 pw.print(" empty="); pw.print(r.empty);
15249                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15250
15251                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15252                     if (r.lastWakeTime != 0) {
15253                         long wtime;
15254                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15255                         synchronized (stats) {
15256                             wtime = stats.getProcessWakeTime(r.info.uid,
15257                                     r.pid, curRealtime);
15258                         }
15259                         long timeUsed = wtime - r.lastWakeTime;
15260                         pw.print(prefix);
15261                         pw.print("    ");
15262                         pw.print("keep awake over ");
15263                         TimeUtils.formatDuration(realtimeSince, pw);
15264                         pw.print(" used ");
15265                         TimeUtils.formatDuration(timeUsed, pw);
15266                         pw.print(" (");
15267                         pw.print((timeUsed*100)/realtimeSince);
15268                         pw.println("%)");
15269                     }
15270                     if (r.lastCpuTime != 0) {
15271                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15272                         pw.print(prefix);
15273                         pw.print("    ");
15274                         pw.print("run cpu over ");
15275                         TimeUtils.formatDuration(uptimeSince, pw);
15276                         pw.print(" used ");
15277                         TimeUtils.formatDuration(timeUsed, pw);
15278                         pw.print(" (");
15279                         pw.print((timeUsed*100)/uptimeSince);
15280                         pw.println("%)");
15281                     }
15282                 }
15283             }
15284         }
15285         return true;
15286     }
15287
15288     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15289             String[] args) {
15290         ArrayList<ProcessRecord> procs;
15291         synchronized (this) {
15292             if (args != null && args.length > start
15293                     && args[start].charAt(0) != '-') {
15294                 procs = new ArrayList<ProcessRecord>();
15295                 int pid = -1;
15296                 try {
15297                     pid = Integer.parseInt(args[start]);
15298                 } catch (NumberFormatException e) {
15299                 }
15300                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15301                     ProcessRecord proc = mLruProcesses.get(i);
15302                     if (proc.pid == pid) {
15303                         procs.add(proc);
15304                     } else if (allPkgs && proc.pkgList != null
15305                             && proc.pkgList.containsKey(args[start])) {
15306                         procs.add(proc);
15307                     } else if (proc.processName.equals(args[start])) {
15308                         procs.add(proc);
15309                     }
15310                 }
15311                 if (procs.size() <= 0) {
15312                     return null;
15313                 }
15314             } else {
15315                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15316             }
15317         }
15318         return procs;
15319     }
15320
15321     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15322             PrintWriter pw, String[] args) {
15323         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15324         if (procs == null) {
15325             pw.println("No process found for: " + args[0]);
15326             return;
15327         }
15328
15329         long uptime = SystemClock.uptimeMillis();
15330         long realtime = SystemClock.elapsedRealtime();
15331         pw.println("Applications Graphics Acceleration Info:");
15332         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15333
15334         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15335             ProcessRecord r = procs.get(i);
15336             if (r.thread != null) {
15337                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15338                 pw.flush();
15339                 try {
15340                     TransferPipe tp = new TransferPipe();
15341                     try {
15342                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15343                         tp.go(fd);
15344                     } finally {
15345                         tp.kill();
15346                     }
15347                 } catch (IOException e) {
15348                     pw.println("Failure while dumping the app: " + r);
15349                     pw.flush();
15350                 } catch (RemoteException e) {
15351                     pw.println("Got a RemoteException while dumping the app " + r);
15352                     pw.flush();
15353                 }
15354             }
15355         }
15356     }
15357
15358     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15359         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15360         if (procs == null) {
15361             pw.println("No process found for: " + args[0]);
15362             return;
15363         }
15364
15365         pw.println("Applications Database Info:");
15366
15367         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15368             ProcessRecord r = procs.get(i);
15369             if (r.thread != null) {
15370                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15371                 pw.flush();
15372                 try {
15373                     TransferPipe tp = new TransferPipe();
15374                     try {
15375                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15376                         tp.go(fd);
15377                     } finally {
15378                         tp.kill();
15379                     }
15380                 } catch (IOException e) {
15381                     pw.println("Failure while dumping the app: " + r);
15382                     pw.flush();
15383                 } catch (RemoteException e) {
15384                     pw.println("Got a RemoteException while dumping the app " + r);
15385                     pw.flush();
15386                 }
15387             }
15388         }
15389     }
15390
15391     final static class MemItem {
15392         final boolean isProc;
15393         final String label;
15394         final String shortLabel;
15395         final long pss;
15396         final long swapPss;
15397         final int id;
15398         final boolean hasActivities;
15399         ArrayList<MemItem> subitems;
15400
15401         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15402                 boolean _hasActivities) {
15403             isProc = true;
15404             label = _label;
15405             shortLabel = _shortLabel;
15406             pss = _pss;
15407             swapPss = _swapPss;
15408             id = _id;
15409             hasActivities = _hasActivities;
15410         }
15411
15412         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15413             isProc = false;
15414             label = _label;
15415             shortLabel = _shortLabel;
15416             pss = _pss;
15417             swapPss = _swapPss;
15418             id = _id;
15419             hasActivities = false;
15420         }
15421     }
15422
15423     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15424             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15425         if (sort && !isCompact) {
15426             Collections.sort(items, new Comparator<MemItem>() {
15427                 @Override
15428                 public int compare(MemItem lhs, MemItem rhs) {
15429                     if (lhs.pss < rhs.pss) {
15430                         return 1;
15431                     } else if (lhs.pss > rhs.pss) {
15432                         return -1;
15433                     }
15434                     return 0;
15435                 }
15436             });
15437         }
15438
15439         for (int i=0; i<items.size(); i++) {
15440             MemItem mi = items.get(i);
15441             if (!isCompact) {
15442                 if (dumpSwapPss) {
15443                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15444                             mi.label, stringifyKBSize(mi.swapPss));
15445                 } else {
15446                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15447                 }
15448             } else if (mi.isProc) {
15449                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15450                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15451                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15452                 pw.println(mi.hasActivities ? ",a" : ",e");
15453             } else {
15454                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15455                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15456             }
15457             if (mi.subitems != null) {
15458                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15459                         true, isCompact, dumpSwapPss);
15460             }
15461         }
15462     }
15463
15464     // These are in KB.
15465     static final long[] DUMP_MEM_BUCKETS = new long[] {
15466         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15467         120*1024, 160*1024, 200*1024,
15468         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15469         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15470     };
15471
15472     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15473             boolean stackLike) {
15474         int start = label.lastIndexOf('.');
15475         if (start >= 0) start++;
15476         else start = 0;
15477         int end = label.length();
15478         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15479             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15480                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15481                 out.append(bucket);
15482                 out.append(stackLike ? "MB." : "MB ");
15483                 out.append(label, start, end);
15484                 return;
15485             }
15486         }
15487         out.append(memKB/1024);
15488         out.append(stackLike ? "MB." : "MB ");
15489         out.append(label, start, end);
15490     }
15491
15492     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15493             ProcessList.NATIVE_ADJ,
15494             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15495             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15496             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15497             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15498             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15499             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15500     };
15501     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15502             "Native",
15503             "System", "Persistent", "Persistent Service", "Foreground",
15504             "Visible", "Perceptible",
15505             "Heavy Weight", "Backup",
15506             "A Services", "Home",
15507             "Previous", "B Services", "Cached"
15508     };
15509     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15510             "native",
15511             "sys", "pers", "persvc", "fore",
15512             "vis", "percept",
15513             "heavy", "backup",
15514             "servicea", "home",
15515             "prev", "serviceb", "cached"
15516     };
15517
15518     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15519             long realtime, boolean isCheckinRequest, boolean isCompact) {
15520         if (isCompact) {
15521             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15522         }
15523         if (isCheckinRequest || isCompact) {
15524             // short checkin version
15525             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15526         } else {
15527             pw.println("Applications Memory Usage (in Kilobytes):");
15528             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15529         }
15530     }
15531
15532     private static final int KSM_SHARED = 0;
15533     private static final int KSM_SHARING = 1;
15534     private static final int KSM_UNSHARED = 2;
15535     private static final int KSM_VOLATILE = 3;
15536
15537     private final long[] getKsmInfo() {
15538         long[] longOut = new long[4];
15539         final int[] SINGLE_LONG_FORMAT = new int[] {
15540             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15541         };
15542         long[] longTmp = new long[1];
15543         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15544                 SINGLE_LONG_FORMAT, null, longTmp, null);
15545         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15546         longTmp[0] = 0;
15547         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15548                 SINGLE_LONG_FORMAT, null, longTmp, null);
15549         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15550         longTmp[0] = 0;
15551         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15552                 SINGLE_LONG_FORMAT, null, longTmp, null);
15553         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15554         longTmp[0] = 0;
15555         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15556                 SINGLE_LONG_FORMAT, null, longTmp, null);
15557         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15558         return longOut;
15559     }
15560
15561     private static String stringifySize(long size, int order) {
15562         Locale locale = Locale.US;
15563         switch (order) {
15564             case 1:
15565                 return String.format(locale, "%,13d", size);
15566             case 1024:
15567                 return String.format(locale, "%,9dK", size / 1024);
15568             case 1024 * 1024:
15569                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15570             case 1024 * 1024 * 1024:
15571                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15572             default:
15573                 throw new IllegalArgumentException("Invalid size order");
15574         }
15575     }
15576
15577     private static String stringifyKBSize(long size) {
15578         return stringifySize(size * 1024, 1024);
15579     }
15580
15581     // Update this version number in case you change the 'compact' format
15582     private static final int MEMINFO_COMPACT_VERSION = 1;
15583
15584     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15585             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15586         boolean dumpDetails = false;
15587         boolean dumpFullDetails = false;
15588         boolean dumpDalvik = false;
15589         boolean dumpSummaryOnly = false;
15590         boolean dumpUnreachable = false;
15591         boolean oomOnly = false;
15592         boolean isCompact = false;
15593         boolean localOnly = false;
15594         boolean packages = false;
15595         boolean isCheckinRequest = false;
15596         boolean dumpSwapPss = false;
15597
15598         int opti = 0;
15599         while (opti < args.length) {
15600             String opt = args[opti];
15601             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15602                 break;
15603             }
15604             opti++;
15605             if ("-a".equals(opt)) {
15606                 dumpDetails = true;
15607                 dumpFullDetails = true;
15608                 dumpDalvik = true;
15609                 dumpSwapPss = true;
15610             } else if ("-d".equals(opt)) {
15611                 dumpDalvik = true;
15612             } else if ("-c".equals(opt)) {
15613                 isCompact = true;
15614             } else if ("-s".equals(opt)) {
15615                 dumpDetails = true;
15616                 dumpSummaryOnly = true;
15617             } else if ("-S".equals(opt)) {
15618                 dumpSwapPss = true;
15619             } else if ("--unreachable".equals(opt)) {
15620                 dumpUnreachable = true;
15621             } else if ("--oom".equals(opt)) {
15622                 oomOnly = true;
15623             } else if ("--local".equals(opt)) {
15624                 localOnly = true;
15625             } else if ("--package".equals(opt)) {
15626                 packages = true;
15627             } else if ("--checkin".equals(opt)) {
15628                 isCheckinRequest = true;
15629
15630             } else if ("-h".equals(opt)) {
15631                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15632                 pw.println("  -a: include all available information for each process.");
15633                 pw.println("  -d: include dalvik details.");
15634                 pw.println("  -c: dump in a compact machine-parseable representation.");
15635                 pw.println("  -s: dump only summary of application memory usage.");
15636                 pw.println("  -S: dump also SwapPss.");
15637                 pw.println("  --oom: only show processes organized by oom adj.");
15638                 pw.println("  --local: only collect details locally, don't call process.");
15639                 pw.println("  --package: interpret process arg as package, dumping all");
15640                 pw.println("             processes that have loaded that package.");
15641                 pw.println("  --checkin: dump data for a checkin");
15642                 pw.println("If [process] is specified it can be the name or ");
15643                 pw.println("pid of a specific process to dump.");
15644                 return;
15645             } else {
15646                 pw.println("Unknown argument: " + opt + "; use -h for help");
15647             }
15648         }
15649
15650         long uptime = SystemClock.uptimeMillis();
15651         long realtime = SystemClock.elapsedRealtime();
15652         final long[] tmpLong = new long[1];
15653
15654         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15655         if (procs == null) {
15656             // No Java processes.  Maybe they want to print a native process.
15657             if (args != null && args.length > opti
15658                     && args[opti].charAt(0) != '-') {
15659                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15660                         = new ArrayList<ProcessCpuTracker.Stats>();
15661                 updateCpuStatsNow();
15662                 int findPid = -1;
15663                 try {
15664                     findPid = Integer.parseInt(args[opti]);
15665                 } catch (NumberFormatException e) {
15666                 }
15667                 synchronized (mProcessCpuTracker) {
15668                     final int N = mProcessCpuTracker.countStats();
15669                     for (int i=0; i<N; i++) {
15670                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15671                         if (st.pid == findPid || (st.baseName != null
15672                                 && st.baseName.equals(args[opti]))) {
15673                             nativeProcs.add(st);
15674                         }
15675                     }
15676                 }
15677                 if (nativeProcs.size() > 0) {
15678                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15679                             isCompact);
15680                     Debug.MemoryInfo mi = null;
15681                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15682                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15683                         final int pid = r.pid;
15684                         if (!isCheckinRequest && dumpDetails) {
15685                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15686                         }
15687                         if (mi == null) {
15688                             mi = new Debug.MemoryInfo();
15689                         }
15690                         if (dumpDetails || (!brief && !oomOnly)) {
15691                             Debug.getMemoryInfo(pid, mi);
15692                         } else {
15693                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15694                             mi.dalvikPrivateDirty = (int)tmpLong[0];
15695                         }
15696                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15697                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15698                         if (isCheckinRequest) {
15699                             pw.println();
15700                         }
15701                     }
15702                     return;
15703                 }
15704             }
15705             pw.println("No process found for: " + args[opti]);
15706             return;
15707         }
15708
15709         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15710             dumpDetails = true;
15711         }
15712
15713         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15714
15715         String[] innerArgs = new String[args.length-opti];
15716         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15717
15718         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15719         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15720         long nativePss = 0;
15721         long nativeSwapPss = 0;
15722         long dalvikPss = 0;
15723         long dalvikSwapPss = 0;
15724         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15725                 EmptyArray.LONG;
15726         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15727                 EmptyArray.LONG;
15728         long otherPss = 0;
15729         long otherSwapPss = 0;
15730         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15731         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15732
15733         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15734         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15735         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15736                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15737
15738         long totalPss = 0;
15739         long totalSwapPss = 0;
15740         long cachedPss = 0;
15741         long cachedSwapPss = 0;
15742         boolean hasSwapPss = false;
15743
15744         Debug.MemoryInfo mi = null;
15745         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15746             final ProcessRecord r = procs.get(i);
15747             final IApplicationThread thread;
15748             final int pid;
15749             final int oomAdj;
15750             final boolean hasActivities;
15751             synchronized (this) {
15752                 thread = r.thread;
15753                 pid = r.pid;
15754                 oomAdj = r.getSetAdjWithServices();
15755                 hasActivities = r.activities.size() > 0;
15756             }
15757             if (thread != null) {
15758                 if (!isCheckinRequest && dumpDetails) {
15759                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15760                 }
15761                 if (mi == null) {
15762                     mi = new Debug.MemoryInfo();
15763                 }
15764                 if (dumpDetails || (!brief && !oomOnly)) {
15765                     Debug.getMemoryInfo(pid, mi);
15766                     hasSwapPss = mi.hasSwappedOutPss;
15767                 } else {
15768                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15769                     mi.dalvikPrivateDirty = (int)tmpLong[0];
15770                 }
15771                 if (dumpDetails) {
15772                     if (localOnly) {
15773                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15774                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15775                         if (isCheckinRequest) {
15776                             pw.println();
15777                         }
15778                     } else {
15779                         try {
15780                             pw.flush();
15781                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15782                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15783                         } catch (RemoteException e) {
15784                             if (!isCheckinRequest) {
15785                                 pw.println("Got RemoteException!");
15786                                 pw.flush();
15787                             }
15788                         }
15789                     }
15790                 }
15791
15792                 final long myTotalPss = mi.getTotalPss();
15793                 final long myTotalUss = mi.getTotalUss();
15794                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15795
15796                 synchronized (this) {
15797                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15798                         // Record this for posterity if the process has been stable.
15799                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15800                     }
15801                 }
15802
15803                 if (!isCheckinRequest && mi != null) {
15804                     totalPss += myTotalPss;
15805                     totalSwapPss += myTotalSwapPss;
15806                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15807                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15808                             myTotalSwapPss, pid, hasActivities);
15809                     procMems.add(pssItem);
15810                     procMemsMap.put(pid, pssItem);
15811
15812                     nativePss += mi.nativePss;
15813                     nativeSwapPss += mi.nativeSwappedOutPss;
15814                     dalvikPss += mi.dalvikPss;
15815                     dalvikSwapPss += mi.dalvikSwappedOutPss;
15816                     for (int j=0; j<dalvikSubitemPss.length; j++) {
15817                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15818                         dalvikSubitemSwapPss[j] +=
15819                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15820                     }
15821                     otherPss += mi.otherPss;
15822                     otherSwapPss += mi.otherSwappedOutPss;
15823                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15824                         long mem = mi.getOtherPss(j);
15825                         miscPss[j] += mem;
15826                         otherPss -= mem;
15827                         mem = mi.getOtherSwappedOutPss(j);
15828                         miscSwapPss[j] += mem;
15829                         otherSwapPss -= mem;
15830                     }
15831
15832                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15833                         cachedPss += myTotalPss;
15834                         cachedSwapPss += myTotalSwapPss;
15835                     }
15836
15837                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15838                         if (oomIndex == (oomPss.length - 1)
15839                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15840                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15841                             oomPss[oomIndex] += myTotalPss;
15842                             oomSwapPss[oomIndex] += myTotalSwapPss;
15843                             if (oomProcs[oomIndex] == null) {
15844                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
15845                             }
15846                             oomProcs[oomIndex].add(pssItem);
15847                             break;
15848                         }
15849                     }
15850                 }
15851             }
15852         }
15853
15854         long nativeProcTotalPss = 0;
15855
15856         if (!isCheckinRequest && procs.size() > 1 && !packages) {
15857             // If we are showing aggregations, also look for native processes to
15858             // include so that our aggregations are more accurate.
15859             updateCpuStatsNow();
15860             mi = null;
15861             synchronized (mProcessCpuTracker) {
15862                 final int N = mProcessCpuTracker.countStats();
15863                 for (int i=0; i<N; i++) {
15864                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15865                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15866                         if (mi == null) {
15867                             mi = new Debug.MemoryInfo();
15868                         }
15869                         if (!brief && !oomOnly) {
15870                             Debug.getMemoryInfo(st.pid, mi);
15871                         } else {
15872                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15873                             mi.nativePrivateDirty = (int)tmpLong[0];
15874                         }
15875
15876                         final long myTotalPss = mi.getTotalPss();
15877                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15878                         totalPss += myTotalPss;
15879                         nativeProcTotalPss += myTotalPss;
15880
15881                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15882                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15883                         procMems.add(pssItem);
15884
15885                         nativePss += mi.nativePss;
15886                         nativeSwapPss += mi.nativeSwappedOutPss;
15887                         dalvikPss += mi.dalvikPss;
15888                         dalvikSwapPss += mi.dalvikSwappedOutPss;
15889                         for (int j=0; j<dalvikSubitemPss.length; j++) {
15890                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15891                             dalvikSubitemSwapPss[j] +=
15892                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15893                         }
15894                         otherPss += mi.otherPss;
15895                         otherSwapPss += mi.otherSwappedOutPss;
15896                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15897                             long mem = mi.getOtherPss(j);
15898                             miscPss[j] += mem;
15899                             otherPss -= mem;
15900                             mem = mi.getOtherSwappedOutPss(j);
15901                             miscSwapPss[j] += mem;
15902                             otherSwapPss -= mem;
15903                         }
15904                         oomPss[0] += myTotalPss;
15905                         oomSwapPss[0] += myTotalSwapPss;
15906                         if (oomProcs[0] == null) {
15907                             oomProcs[0] = new ArrayList<MemItem>();
15908                         }
15909                         oomProcs[0].add(pssItem);
15910                     }
15911                 }
15912             }
15913
15914             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15915
15916             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15917             final MemItem dalvikItem =
15918                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15919             if (dalvikSubitemPss.length > 0) {
15920                 dalvikItem.subitems = new ArrayList<MemItem>();
15921                 for (int j=0; j<dalvikSubitemPss.length; j++) {
15922                     final String name = Debug.MemoryInfo.getOtherLabel(
15923                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
15924                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15925                                     dalvikSubitemSwapPss[j], j));
15926                 }
15927             }
15928             catMems.add(dalvikItem);
15929             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15930             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15931                 String label = Debug.MemoryInfo.getOtherLabel(j);
15932                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15933             }
15934
15935             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15936             for (int j=0; j<oomPss.length; j++) {
15937                 if (oomPss[j] != 0) {
15938                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15939                             : DUMP_MEM_OOM_LABEL[j];
15940                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15941                             DUMP_MEM_OOM_ADJ[j]);
15942                     item.subitems = oomProcs[j];
15943                     oomMems.add(item);
15944                 }
15945             }
15946
15947             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15948             if (!brief && !oomOnly && !isCompact) {
15949                 pw.println();
15950                 pw.println("Total PSS by process:");
15951                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15952                 pw.println();
15953             }
15954             if (!isCompact) {
15955                 pw.println("Total PSS by OOM adjustment:");
15956             }
15957             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15958             if (!brief && !oomOnly) {
15959                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15960                 if (!isCompact) {
15961                     out.println();
15962                     out.println("Total PSS by category:");
15963                 }
15964                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15965             }
15966             if (!isCompact) {
15967                 pw.println();
15968             }
15969             MemInfoReader memInfo = new MemInfoReader();
15970             memInfo.readMemInfo();
15971             if (nativeProcTotalPss > 0) {
15972                 synchronized (this) {
15973                     final long cachedKb = memInfo.getCachedSizeKb();
15974                     final long freeKb = memInfo.getFreeSizeKb();
15975                     final long zramKb = memInfo.getZramTotalSizeKb();
15976                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15977                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15978                             kernelKb*1024, nativeProcTotalPss*1024);
15979                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15980                             nativeProcTotalPss);
15981                 }
15982             }
15983             if (!brief) {
15984                 if (!isCompact) {
15985                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15986                     pw.print(" (status ");
15987                     switch (mLastMemoryLevel) {
15988                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15989                             pw.println("normal)");
15990                             break;
15991                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15992                             pw.println("moderate)");
15993                             break;
15994                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15995                             pw.println("low)");
15996                             break;
15997                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15998                             pw.println("critical)");
15999                             break;
16000                         default:
16001                             pw.print(mLastMemoryLevel);
16002                             pw.println(")");
16003                             break;
16004                     }
16005                     pw.print(" Free RAM: ");
16006                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16007                             + memInfo.getFreeSizeKb()));
16008                     pw.print(" (");
16009                     pw.print(stringifyKBSize(cachedPss));
16010                     pw.print(" cached pss + ");
16011                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16012                     pw.print(" cached kernel + ");
16013                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16014                     pw.println(" free)");
16015                 } else {
16016                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16017                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16018                             + memInfo.getFreeSizeKb()); pw.print(",");
16019                     pw.println(totalPss - cachedPss);
16020                 }
16021             }
16022             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16023                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16024                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16025             if (!isCompact) {
16026                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16027                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16028                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16029                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16030                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16031             } else {
16032                 pw.print("lostram,"); pw.println(lostRAM);
16033             }
16034             if (!brief) {
16035                 if (memInfo.getZramTotalSizeKb() != 0) {
16036                     if (!isCompact) {
16037                         pw.print("     ZRAM: ");
16038                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16039                                 pw.print(" physical used for ");
16040                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16041                                         - memInfo.getSwapFreeSizeKb()));
16042                                 pw.print(" in swap (");
16043                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16044                                 pw.println(" total swap)");
16045                     } else {
16046                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16047                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16048                                 pw.println(memInfo.getSwapFreeSizeKb());
16049                     }
16050                 }
16051                 final long[] ksm = getKsmInfo();
16052                 if (!isCompact) {
16053                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16054                             || ksm[KSM_VOLATILE] != 0) {
16055                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16056                                 pw.print(" saved from shared ");
16057                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16058                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16059                                 pw.print(" unshared; ");
16060                                 pw.print(stringifyKBSize(
16061                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16062                     }
16063                     pw.print("   Tuning: ");
16064                     pw.print(ActivityManager.staticGetMemoryClass());
16065                     pw.print(" (large ");
16066                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16067                     pw.print("), oom ");
16068                     pw.print(stringifySize(
16069                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16070                     pw.print(", restore limit ");
16071                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16072                     if (ActivityManager.isLowRamDeviceStatic()) {
16073                         pw.print(" (low-ram)");
16074                     }
16075                     if (ActivityManager.isHighEndGfx()) {
16076                         pw.print(" (high-end-gfx)");
16077                     }
16078                     pw.println();
16079                 } else {
16080                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16081                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16082                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16083                     pw.print("tuning,");
16084                     pw.print(ActivityManager.staticGetMemoryClass());
16085                     pw.print(',');
16086                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16087                     pw.print(',');
16088                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16089                     if (ActivityManager.isLowRamDeviceStatic()) {
16090                         pw.print(",low-ram");
16091                     }
16092                     if (ActivityManager.isHighEndGfx()) {
16093                         pw.print(",high-end-gfx");
16094                     }
16095                     pw.println();
16096                 }
16097             }
16098         }
16099     }
16100
16101     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16102             long memtrack, String name) {
16103         sb.append("  ");
16104         sb.append(ProcessList.makeOomAdjString(oomAdj));
16105         sb.append(' ');
16106         sb.append(ProcessList.makeProcStateString(procState));
16107         sb.append(' ');
16108         ProcessList.appendRamKb(sb, pss);
16109         sb.append(": ");
16110         sb.append(name);
16111         if (memtrack > 0) {
16112             sb.append(" (");
16113             sb.append(stringifyKBSize(memtrack));
16114             sb.append(" memtrack)");
16115         }
16116     }
16117
16118     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16119         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16120         sb.append(" (pid ");
16121         sb.append(mi.pid);
16122         sb.append(") ");
16123         sb.append(mi.adjType);
16124         sb.append('\n');
16125         if (mi.adjReason != null) {
16126             sb.append("                      ");
16127             sb.append(mi.adjReason);
16128             sb.append('\n');
16129         }
16130     }
16131
16132     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16133         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16134         for (int i=0, N=memInfos.size(); i<N; i++) {
16135             ProcessMemInfo mi = memInfos.get(i);
16136             infoMap.put(mi.pid, mi);
16137         }
16138         updateCpuStatsNow();
16139         long[] memtrackTmp = new long[1];
16140         synchronized (mProcessCpuTracker) {
16141             final int N = mProcessCpuTracker.countStats();
16142             for (int i=0; i<N; i++) {
16143                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16144                 if (st.vsize > 0) {
16145                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
16146                     if (pss > 0) {
16147                         if (infoMap.indexOfKey(st.pid) < 0) {
16148                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16149                                     ProcessList.NATIVE_ADJ, -1, "native", null);
16150                             mi.pss = pss;
16151                             mi.memtrack = memtrackTmp[0];
16152                             memInfos.add(mi);
16153                         }
16154                     }
16155                 }
16156             }
16157         }
16158
16159         long totalPss = 0;
16160         long totalMemtrack = 0;
16161         for (int i=0, N=memInfos.size(); i<N; i++) {
16162             ProcessMemInfo mi = memInfos.get(i);
16163             if (mi.pss == 0) {
16164                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16165                 mi.memtrack = memtrackTmp[0];
16166             }
16167             totalPss += mi.pss;
16168             totalMemtrack += mi.memtrack;
16169         }
16170         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16171             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16172                 if (lhs.oomAdj != rhs.oomAdj) {
16173                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16174                 }
16175                 if (lhs.pss != rhs.pss) {
16176                     return lhs.pss < rhs.pss ? 1 : -1;
16177                 }
16178                 return 0;
16179             }
16180         });
16181
16182         StringBuilder tag = new StringBuilder(128);
16183         StringBuilder stack = new StringBuilder(128);
16184         tag.append("Low on memory -- ");
16185         appendMemBucket(tag, totalPss, "total", false);
16186         appendMemBucket(stack, totalPss, "total", true);
16187
16188         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16189         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16190         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16191
16192         boolean firstLine = true;
16193         int lastOomAdj = Integer.MIN_VALUE;
16194         long extraNativeRam = 0;
16195         long extraNativeMemtrack = 0;
16196         long cachedPss = 0;
16197         for (int i=0, N=memInfos.size(); i<N; i++) {
16198             ProcessMemInfo mi = memInfos.get(i);
16199
16200             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16201                 cachedPss += mi.pss;
16202             }
16203
16204             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16205                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16206                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16207                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16208                 if (lastOomAdj != mi.oomAdj) {
16209                     lastOomAdj = mi.oomAdj;
16210                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16211                         tag.append(" / ");
16212                     }
16213                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16214                         if (firstLine) {
16215                             stack.append(":");
16216                             firstLine = false;
16217                         }
16218                         stack.append("\n\t at ");
16219                     } else {
16220                         stack.append("$");
16221                     }
16222                 } else {
16223                     tag.append(" ");
16224                     stack.append("$");
16225                 }
16226                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16227                     appendMemBucket(tag, mi.pss, mi.name, false);
16228                 }
16229                 appendMemBucket(stack, mi.pss, mi.name, true);
16230                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16231                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16232                     stack.append("(");
16233                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16234                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16235                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16236                             stack.append(":");
16237                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16238                         }
16239                     }
16240                     stack.append(")");
16241                 }
16242             }
16243
16244             appendMemInfo(fullNativeBuilder, mi);
16245             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16246                 // The short form only has native processes that are >= 512K.
16247                 if (mi.pss >= 512) {
16248                     appendMemInfo(shortNativeBuilder, mi);
16249                 } else {
16250                     extraNativeRam += mi.pss;
16251                     extraNativeMemtrack += mi.memtrack;
16252                 }
16253             } else {
16254                 // Short form has all other details, but if we have collected RAM
16255                 // from smaller native processes let's dump a summary of that.
16256                 if (extraNativeRam > 0) {
16257                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16258                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16259                     shortNativeBuilder.append('\n');
16260                     extraNativeRam = 0;
16261                 }
16262                 appendMemInfo(fullJavaBuilder, mi);
16263             }
16264         }
16265
16266         fullJavaBuilder.append("           ");
16267         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16268         fullJavaBuilder.append(": TOTAL");
16269         if (totalMemtrack > 0) {
16270             fullJavaBuilder.append(" (");
16271             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16272             fullJavaBuilder.append(" memtrack)");
16273         } else {
16274         }
16275         fullJavaBuilder.append("\n");
16276
16277         MemInfoReader memInfo = new MemInfoReader();
16278         memInfo.readMemInfo();
16279         final long[] infos = memInfo.getRawInfo();
16280
16281         StringBuilder memInfoBuilder = new StringBuilder(1024);
16282         Debug.getMemInfo(infos);
16283         memInfoBuilder.append("  MemInfo: ");
16284         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16285         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16286         memInfoBuilder.append(stringifyKBSize(
16287                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16288         memInfoBuilder.append(stringifyKBSize(
16289                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16290         memInfoBuilder.append(stringifyKBSize(
16291                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16292         memInfoBuilder.append("           ");
16293         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16294         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16295         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16296         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16297         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16298             memInfoBuilder.append("  ZRAM: ");
16299             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16300             memInfoBuilder.append(" RAM, ");
16301             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16302             memInfoBuilder.append(" swap total, ");
16303             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16304             memInfoBuilder.append(" swap free\n");
16305         }
16306         final long[] ksm = getKsmInfo();
16307         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16308                 || ksm[KSM_VOLATILE] != 0) {
16309             memInfoBuilder.append("  KSM: ");
16310             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16311             memInfoBuilder.append(" saved from shared ");
16312             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16313             memInfoBuilder.append("\n       ");
16314             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16315             memInfoBuilder.append(" unshared; ");
16316             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16317             memInfoBuilder.append(" volatile\n");
16318         }
16319         memInfoBuilder.append("  Free RAM: ");
16320         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16321                 + memInfo.getFreeSizeKb()));
16322         memInfoBuilder.append("\n");
16323         memInfoBuilder.append("  Used RAM: ");
16324         memInfoBuilder.append(stringifyKBSize(
16325                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16326         memInfoBuilder.append("\n");
16327         memInfoBuilder.append("  Lost RAM: ");
16328         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16329                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16330                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16331         memInfoBuilder.append("\n");
16332         Slog.i(TAG, "Low on memory:");
16333         Slog.i(TAG, shortNativeBuilder.toString());
16334         Slog.i(TAG, fullJavaBuilder.toString());
16335         Slog.i(TAG, memInfoBuilder.toString());
16336
16337         StringBuilder dropBuilder = new StringBuilder(1024);
16338         /*
16339         StringWriter oomSw = new StringWriter();
16340         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16341         StringWriter catSw = new StringWriter();
16342         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16343         String[] emptyArgs = new String[] { };
16344         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16345         oomPw.flush();
16346         String oomString = oomSw.toString();
16347         */
16348         dropBuilder.append("Low on memory:");
16349         dropBuilder.append(stack);
16350         dropBuilder.append('\n');
16351         dropBuilder.append(fullNativeBuilder);
16352         dropBuilder.append(fullJavaBuilder);
16353         dropBuilder.append('\n');
16354         dropBuilder.append(memInfoBuilder);
16355         dropBuilder.append('\n');
16356         /*
16357         dropBuilder.append(oomString);
16358         dropBuilder.append('\n');
16359         */
16360         StringWriter catSw = new StringWriter();
16361         synchronized (ActivityManagerService.this) {
16362             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16363             String[] emptyArgs = new String[] { };
16364             catPw.println();
16365             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16366             catPw.println();
16367             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16368                     false, null).dumpLocked();
16369             catPw.println();
16370             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16371             catPw.flush();
16372         }
16373         dropBuilder.append(catSw.toString());
16374         addErrorToDropBox("lowmem", null, "system_server", null,
16375                 null, tag.toString(), dropBuilder.toString(), null, null);
16376         //Slog.i(TAG, "Sent to dropbox:");
16377         //Slog.i(TAG, dropBuilder.toString());
16378         synchronized (ActivityManagerService.this) {
16379             long now = SystemClock.uptimeMillis();
16380             if (mLastMemUsageReportTime < now) {
16381                 mLastMemUsageReportTime = now;
16382             }
16383         }
16384     }
16385
16386     /**
16387      * Searches array of arguments for the specified string
16388      * @param args array of argument strings
16389      * @param value value to search for
16390      * @return true if the value is contained in the array
16391      */
16392     private static boolean scanArgs(String[] args, String value) {
16393         if (args != null) {
16394             for (String arg : args) {
16395                 if (value.equals(arg)) {
16396                     return true;
16397                 }
16398             }
16399         }
16400         return false;
16401     }
16402
16403     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16404             ContentProviderRecord cpr, boolean always) {
16405         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16406
16407         if (!inLaunching || always) {
16408             synchronized (cpr) {
16409                 cpr.launchingApp = null;
16410                 cpr.notifyAll();
16411             }
16412             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16413             String names[] = cpr.info.authority.split(";");
16414             for (int j = 0; j < names.length; j++) {
16415                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16416             }
16417         }
16418
16419         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16420             ContentProviderConnection conn = cpr.connections.get(i);
16421             if (conn.waiting) {
16422                 // If this connection is waiting for the provider, then we don't
16423                 // need to mess with its process unless we are always removing
16424                 // or for some reason the provider is not currently launching.
16425                 if (inLaunching && !always) {
16426                     continue;
16427                 }
16428             }
16429             ProcessRecord capp = conn.client;
16430             conn.dead = true;
16431             if (conn.stableCount > 0) {
16432                 if (!capp.persistent && capp.thread != null
16433                         && capp.pid != 0
16434                         && capp.pid != MY_PID) {
16435                     capp.kill("depends on provider "
16436                             + cpr.name.flattenToShortString()
16437                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16438                 }
16439             } else if (capp.thread != null && conn.provider.provider != null) {
16440                 try {
16441                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16442                 } catch (RemoteException e) {
16443                 }
16444                 // In the protocol here, we don't expect the client to correctly
16445                 // clean up this connection, we'll just remove it.
16446                 cpr.connections.remove(i);
16447                 if (conn.client.conProviders.remove(conn)) {
16448                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16449                 }
16450             }
16451         }
16452
16453         if (inLaunching && always) {
16454             mLaunchingProviders.remove(cpr);
16455         }
16456         return inLaunching;
16457     }
16458
16459     /**
16460      * Main code for cleaning up a process when it has gone away.  This is
16461      * called both as a result of the process dying, or directly when stopping
16462      * a process when running in single process mode.
16463      *
16464      * @return Returns true if the given process has been restarted, so the
16465      * app that was passed in must remain on the process lists.
16466      */
16467     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16468             boolean restarting, boolean allowRestart, int index) {
16469         if (index >= 0) {
16470             removeLruProcessLocked(app);
16471             ProcessList.remove(app.pid);
16472         }
16473
16474         mProcessesToGc.remove(app);
16475         mPendingPssProcesses.remove(app);
16476
16477         // Dismiss any open dialogs.
16478         if (app.crashDialog != null && !app.forceCrashReport) {
16479             app.crashDialog.dismiss();
16480             app.crashDialog = null;
16481         }
16482         if (app.anrDialog != null) {
16483             app.anrDialog.dismiss();
16484             app.anrDialog = null;
16485         }
16486         if (app.waitDialog != null) {
16487             app.waitDialog.dismiss();
16488             app.waitDialog = null;
16489         }
16490
16491         app.crashing = false;
16492         app.notResponding = false;
16493
16494         app.resetPackageList(mProcessStats);
16495         app.unlinkDeathRecipient();
16496         app.makeInactive(mProcessStats);
16497         app.waitingToKill = null;
16498         app.forcingToForeground = null;
16499         updateProcessForegroundLocked(app, false, false);
16500         app.foregroundActivities = false;
16501         app.hasShownUi = false;
16502         app.treatLikeActivity = false;
16503         app.hasAboveClient = false;
16504         app.hasClientActivities = false;
16505
16506         mServices.killServicesLocked(app, allowRestart);
16507
16508         boolean restart = false;
16509
16510         // Remove published content providers.
16511         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16512             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16513             final boolean always = app.bad || !allowRestart;
16514             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16515             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16516                 // We left the provider in the launching list, need to
16517                 // restart it.
16518                 restart = true;
16519             }
16520
16521             cpr.provider = null;
16522             cpr.proc = null;
16523         }
16524         app.pubProviders.clear();
16525
16526         // Take care of any launching providers waiting for this process.
16527         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16528             restart = true;
16529         }
16530
16531         // Unregister from connected content providers.
16532         if (!app.conProviders.isEmpty()) {
16533             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16534                 ContentProviderConnection conn = app.conProviders.get(i);
16535                 conn.provider.connections.remove(conn);
16536                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16537                         conn.provider.name);
16538             }
16539             app.conProviders.clear();
16540         }
16541
16542         // At this point there may be remaining entries in mLaunchingProviders
16543         // where we were the only one waiting, so they are no longer of use.
16544         // Look for these and clean up if found.
16545         // XXX Commented out for now.  Trying to figure out a way to reproduce
16546         // the actual situation to identify what is actually going on.
16547         if (false) {
16548             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16549                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16550                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16551                     synchronized (cpr) {
16552                         cpr.launchingApp = null;
16553                         cpr.notifyAll();
16554                     }
16555                 }
16556             }
16557         }
16558
16559         skipCurrentReceiverLocked(app);
16560
16561         // Unregister any receivers.
16562         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16563             removeReceiverLocked(app.receivers.valueAt(i));
16564         }
16565         app.receivers.clear();
16566
16567         // If the app is undergoing backup, tell the backup manager about it
16568         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16569             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16570                     + mBackupTarget.appInfo + " died during backup");
16571             try {
16572                 IBackupManager bm = IBackupManager.Stub.asInterface(
16573                         ServiceManager.getService(Context.BACKUP_SERVICE));
16574                 bm.agentDisconnected(app.info.packageName);
16575             } catch (RemoteException e) {
16576                 // can't happen; backup manager is local
16577             }
16578         }
16579
16580         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16581             ProcessChangeItem item = mPendingProcessChanges.get(i);
16582             if (item.pid == app.pid) {
16583                 mPendingProcessChanges.remove(i);
16584                 mAvailProcessChanges.add(item);
16585             }
16586         }
16587         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16588                 null).sendToTarget();
16589
16590         // If the caller is restarting this app, then leave it in its
16591         // current lists and let the caller take care of it.
16592         if (restarting) {
16593             return false;
16594         }
16595
16596         if (!app.persistent || app.isolated) {
16597             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16598                     "Removing non-persistent process during cleanup: " + app);
16599             removeProcessNameLocked(app.processName, app.uid);
16600             if (mHeavyWeightProcess == app) {
16601                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16602                         mHeavyWeightProcess.userId, 0));
16603                 mHeavyWeightProcess = null;
16604             }
16605         } else if (!app.removed) {
16606             // This app is persistent, so we need to keep its record around.
16607             // If it is not already on the pending app list, add it there
16608             // and start a new process for it.
16609             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16610                 mPersistentStartingProcesses.add(app);
16611                 restart = true;
16612             }
16613         }
16614         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16615                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16616         mProcessesOnHold.remove(app);
16617
16618         if (app == mHomeProcess) {
16619             mHomeProcess = null;
16620         }
16621         if (app == mPreviousProcess) {
16622             mPreviousProcess = null;
16623         }
16624
16625         if (restart && !app.isolated) {
16626             // We have components that still need to be running in the
16627             // process, so re-launch it.
16628             if (index < 0) {
16629                 ProcessList.remove(app.pid);
16630             }
16631             addProcessNameLocked(app);
16632             startProcessLocked(app, "restart", app.processName);
16633             return true;
16634         } else if (app.pid > 0 && app.pid != MY_PID) {
16635             // Goodbye!
16636             boolean removed;
16637             synchronized (mPidsSelfLocked) {
16638                 mPidsSelfLocked.remove(app.pid);
16639                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16640             }
16641             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16642             if (app.isolated) {
16643                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16644             }
16645             app.setPid(0);
16646         }
16647         return false;
16648     }
16649
16650     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16651         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16652             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16653             if (cpr.launchingApp == app) {
16654                 return true;
16655             }
16656         }
16657         return false;
16658     }
16659
16660     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16661         // Look through the content providers we are waiting to have launched,
16662         // and if any run in this process then either schedule a restart of
16663         // the process or kill the client waiting for it if this process has
16664         // gone bad.
16665         boolean restart = false;
16666         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16667             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16668             if (cpr.launchingApp == app) {
16669                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16670                     restart = true;
16671                 } else {
16672                     removeDyingProviderLocked(app, cpr, true);
16673                 }
16674             }
16675         }
16676         return restart;
16677     }
16678
16679     // =========================================================
16680     // SERVICES
16681     // =========================================================
16682
16683     @Override
16684     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16685             int flags) {
16686         enforceNotIsolatedCaller("getServices");
16687         synchronized (this) {
16688             return mServices.getRunningServiceInfoLocked(maxNum, flags);
16689         }
16690     }
16691
16692     @Override
16693     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16694         enforceNotIsolatedCaller("getRunningServiceControlPanel");
16695         synchronized (this) {
16696             return mServices.getRunningServiceControlPanelLocked(name);
16697         }
16698     }
16699
16700     @Override
16701     public ComponentName startService(IApplicationThread caller, Intent service,
16702             String resolvedType, String callingPackage, int userId)
16703             throws TransactionTooLargeException {
16704         enforceNotIsolatedCaller("startService");
16705         // Refuse possible leaked file descriptors
16706         if (service != null && service.hasFileDescriptors() == true) {
16707             throw new IllegalArgumentException("File descriptors passed in Intent");
16708         }
16709
16710         if (callingPackage == null) {
16711             throw new IllegalArgumentException("callingPackage cannot be null");
16712         }
16713
16714         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16715                 "startService: " + service + " type=" + resolvedType);
16716         synchronized(this) {
16717             final int callingPid = Binder.getCallingPid();
16718             final int callingUid = Binder.getCallingUid();
16719             final long origId = Binder.clearCallingIdentity();
16720             ComponentName res = mServices.startServiceLocked(caller, service,
16721                     resolvedType, callingPid, callingUid, callingPackage, userId);
16722             Binder.restoreCallingIdentity(origId);
16723             return res;
16724         }
16725     }
16726
16727     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16728             String callingPackage, int userId)
16729             throws TransactionTooLargeException {
16730         synchronized(this) {
16731             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16732                     "startServiceInPackage: " + service + " type=" + resolvedType);
16733             final long origId = Binder.clearCallingIdentity();
16734             ComponentName res = mServices.startServiceLocked(null, service,
16735                     resolvedType, -1, uid, callingPackage, userId);
16736             Binder.restoreCallingIdentity(origId);
16737             return res;
16738         }
16739     }
16740
16741     @Override
16742     public int stopService(IApplicationThread caller, Intent service,
16743             String resolvedType, int userId) {
16744         enforceNotIsolatedCaller("stopService");
16745         // Refuse possible leaked file descriptors
16746         if (service != null && service.hasFileDescriptors() == true) {
16747             throw new IllegalArgumentException("File descriptors passed in Intent");
16748         }
16749
16750         synchronized(this) {
16751             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16752         }
16753     }
16754
16755     @Override
16756     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16757         enforceNotIsolatedCaller("peekService");
16758         // Refuse possible leaked file descriptors
16759         if (service != null && service.hasFileDescriptors() == true) {
16760             throw new IllegalArgumentException("File descriptors passed in Intent");
16761         }
16762
16763         if (callingPackage == null) {
16764             throw new IllegalArgumentException("callingPackage cannot be null");
16765         }
16766
16767         synchronized(this) {
16768             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16769         }
16770     }
16771
16772     @Override
16773     public boolean stopServiceToken(ComponentName className, IBinder token,
16774             int startId) {
16775         synchronized(this) {
16776             return mServices.stopServiceTokenLocked(className, token, startId);
16777         }
16778     }
16779
16780     @Override
16781     public void setServiceForeground(ComponentName className, IBinder token,
16782             int id, Notification notification, int flags) {
16783         synchronized(this) {
16784             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16785         }
16786     }
16787
16788     @Override
16789     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16790             boolean requireFull, String name, String callerPackage) {
16791         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16792                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16793     }
16794
16795     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16796             String className, int flags) {
16797         boolean result = false;
16798         // For apps that don't have pre-defined UIDs, check for permission
16799         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16800             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16801                 if (ActivityManager.checkUidPermission(
16802                         INTERACT_ACROSS_USERS,
16803                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16804                     ComponentName comp = new ComponentName(aInfo.packageName, className);
16805                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
16806                             + " requests FLAG_SINGLE_USER, but app does not hold "
16807                             + INTERACT_ACROSS_USERS;
16808                     Slog.w(TAG, msg);
16809                     throw new SecurityException(msg);
16810                 }
16811                 // Permission passed
16812                 result = true;
16813             }
16814         } else if ("system".equals(componentProcessName)) {
16815             result = true;
16816         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16817             // Phone app and persistent apps are allowed to export singleuser providers.
16818             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16819                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16820         }
16821         if (DEBUG_MU) Slog.v(TAG_MU,
16822                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16823                 + Integer.toHexString(flags) + ") = " + result);
16824         return result;
16825     }
16826
16827     /**
16828      * Checks to see if the caller is in the same app as the singleton
16829      * component, or the component is in a special app. It allows special apps
16830      * to export singleton components but prevents exporting singleton
16831      * components for regular apps.
16832      */
16833     boolean isValidSingletonCall(int callingUid, int componentUid) {
16834         int componentAppId = UserHandle.getAppId(componentUid);
16835         return UserHandle.isSameApp(callingUid, componentUid)
16836                 || componentAppId == Process.SYSTEM_UID
16837                 || componentAppId == Process.PHONE_UID
16838                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16839                         == PackageManager.PERMISSION_GRANTED;
16840     }
16841
16842     public int bindService(IApplicationThread caller, IBinder token, Intent service,
16843             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16844             int userId) throws TransactionTooLargeException {
16845         enforceNotIsolatedCaller("bindService");
16846
16847         // Refuse possible leaked file descriptors
16848         if (service != null && service.hasFileDescriptors() == true) {
16849             throw new IllegalArgumentException("File descriptors passed in Intent");
16850         }
16851
16852         if (callingPackage == null) {
16853             throw new IllegalArgumentException("callingPackage cannot be null");
16854         }
16855
16856         synchronized(this) {
16857             return mServices.bindServiceLocked(caller, token, service,
16858                     resolvedType, connection, flags, callingPackage, userId);
16859         }
16860     }
16861
16862     public boolean unbindService(IServiceConnection connection) {
16863         synchronized (this) {
16864             return mServices.unbindServiceLocked(connection);
16865         }
16866     }
16867
16868     public void publishService(IBinder token, Intent intent, IBinder service) {
16869         // Refuse possible leaked file descriptors
16870         if (intent != null && intent.hasFileDescriptors() == true) {
16871             throw new IllegalArgumentException("File descriptors passed in Intent");
16872         }
16873
16874         synchronized(this) {
16875             if (!(token instanceof ServiceRecord)) {
16876                 throw new IllegalArgumentException("Invalid service token");
16877             }
16878             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16879         }
16880     }
16881
16882     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16883         // Refuse possible leaked file descriptors
16884         if (intent != null && intent.hasFileDescriptors() == true) {
16885             throw new IllegalArgumentException("File descriptors passed in Intent");
16886         }
16887
16888         synchronized(this) {
16889             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16890         }
16891     }
16892
16893     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16894         synchronized(this) {
16895             if (!(token instanceof ServiceRecord)) {
16896                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16897                 throw new IllegalArgumentException("Invalid service token");
16898             }
16899             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16900         }
16901     }
16902
16903     // =========================================================
16904     // BACKUP AND RESTORE
16905     // =========================================================
16906
16907     // Cause the target app to be launched if necessary and its backup agent
16908     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16909     // activity manager to announce its creation.
16910     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16911         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16912                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16913         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16914
16915         synchronized(this) {
16916             // !!! TODO: currently no check here that we're already bound
16917             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16918             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16919             synchronized (stats) {
16920                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16921             }
16922
16923             // Backup agent is now in use, its package can't be stopped.
16924             try {
16925                 AppGlobals.getPackageManager().setPackageStoppedState(
16926                         app.packageName, false, UserHandle.getUserId(app.uid));
16927             } catch (RemoteException e) {
16928             } catch (IllegalArgumentException e) {
16929                 Slog.w(TAG, "Failed trying to unstop package "
16930                         + app.packageName + ": " + e);
16931             }
16932
16933             BackupRecord r = new BackupRecord(ss, app, backupMode);
16934             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16935                     ? new ComponentName(app.packageName, app.backupAgentName)
16936                     : new ComponentName("android", "FullBackupAgent");
16937             // startProcessLocked() returns existing proc's record if it's already running
16938             ProcessRecord proc = startProcessLocked(app.processName, app,
16939                     false, 0, "backup", hostingName, false, false, false);
16940             if (proc == null) {
16941                 Slog.e(TAG, "Unable to start backup agent process " + r);
16942                 return false;
16943             }
16944
16945             // If the app is a regular app (uid >= 10000) and not the system server or phone
16946             // process, etc, then mark it as being in full backup so that certain calls to the
16947             // process can be blocked. This is not reset to false anywhere because we kill the
16948             // process after the full backup is done and the ProcessRecord will vaporize anyway.
16949             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16950                 proc.inFullBackup = true;
16951             }
16952             r.app = proc;
16953             mBackupTarget = r;
16954             mBackupAppName = app.packageName;
16955
16956             // Try not to kill the process during backup
16957             updateOomAdjLocked(proc);
16958
16959             // If the process is already attached, schedule the creation of the backup agent now.
16960             // If it is not yet live, this will be done when it attaches to the framework.
16961             if (proc.thread != null) {
16962                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16963                 try {
16964                     proc.thread.scheduleCreateBackupAgent(app,
16965                             compatibilityInfoForPackageLocked(app), backupMode);
16966                 } catch (RemoteException e) {
16967                     // Will time out on the backup manager side
16968                 }
16969             } else {
16970                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16971             }
16972             // Invariants: at this point, the target app process exists and the application
16973             // is either already running or in the process of coming up.  mBackupTarget and
16974             // mBackupAppName describe the app, so that when it binds back to the AM we
16975             // know that it's scheduled for a backup-agent operation.
16976         }
16977
16978         return true;
16979     }
16980
16981     @Override
16982     public void clearPendingBackup() {
16983         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16984         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16985
16986         synchronized (this) {
16987             mBackupTarget = null;
16988             mBackupAppName = null;
16989         }
16990     }
16991
16992     // A backup agent has just come up
16993     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16994         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16995                 + " = " + agent);
16996
16997         synchronized(this) {
16998             if (!agentPackageName.equals(mBackupAppName)) {
16999                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17000                 return;
17001             }
17002         }
17003
17004         long oldIdent = Binder.clearCallingIdentity();
17005         try {
17006             IBackupManager bm = IBackupManager.Stub.asInterface(
17007                     ServiceManager.getService(Context.BACKUP_SERVICE));
17008             bm.agentConnected(agentPackageName, agent);
17009         } catch (RemoteException e) {
17010             // can't happen; the backup manager service is local
17011         } catch (Exception e) {
17012             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17013             e.printStackTrace();
17014         } finally {
17015             Binder.restoreCallingIdentity(oldIdent);
17016         }
17017     }
17018
17019     // done with this agent
17020     public void unbindBackupAgent(ApplicationInfo appInfo) {
17021         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17022         if (appInfo == null) {
17023             Slog.w(TAG, "unbind backup agent for null app");
17024             return;
17025         }
17026
17027         synchronized(this) {
17028             try {
17029                 if (mBackupAppName == null) {
17030                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17031                     return;
17032                 }
17033
17034                 if (!mBackupAppName.equals(appInfo.packageName)) {
17035                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17036                     return;
17037                 }
17038
17039                 // Not backing this app up any more; reset its OOM adjustment
17040                 final ProcessRecord proc = mBackupTarget.app;
17041                 updateOomAdjLocked(proc);
17042
17043                 // If the app crashed during backup, 'thread' will be null here
17044                 if (proc.thread != null) {
17045                     try {
17046                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17047                                 compatibilityInfoForPackageLocked(appInfo));
17048                     } catch (Exception e) {
17049                         Slog.e(TAG, "Exception when unbinding backup agent:");
17050                         e.printStackTrace();
17051                     }
17052                 }
17053             } finally {
17054                 mBackupTarget = null;
17055                 mBackupAppName = null;
17056             }
17057         }
17058     }
17059     // =========================================================
17060     // BROADCASTS
17061     // =========================================================
17062
17063     boolean isPendingBroadcastProcessLocked(int pid) {
17064         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17065                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17066     }
17067
17068     void skipPendingBroadcastLocked(int pid) {
17069             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17070             for (BroadcastQueue queue : mBroadcastQueues) {
17071                 queue.skipPendingBroadcastLocked(pid);
17072             }
17073     }
17074
17075     // The app just attached; send any pending broadcasts that it should receive
17076     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17077         boolean didSomething = false;
17078         for (BroadcastQueue queue : mBroadcastQueues) {
17079             didSomething |= queue.sendPendingBroadcastsLocked(app);
17080         }
17081         return didSomething;
17082     }
17083
17084     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17085             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17086         enforceNotIsolatedCaller("registerReceiver");
17087         ArrayList<Intent> stickyIntents = null;
17088         ProcessRecord callerApp = null;
17089         int callingUid;
17090         int callingPid;
17091         synchronized(this) {
17092             if (caller != null) {
17093                 callerApp = getRecordForAppLocked(caller);
17094                 if (callerApp == null) {
17095                     throw new SecurityException(
17096                             "Unable to find app for caller " + caller
17097                             + " (pid=" + Binder.getCallingPid()
17098                             + ") when registering receiver " + receiver);
17099                 }
17100                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17101                         !callerApp.pkgList.containsKey(callerPackage) &&
17102                         !"android".equals(callerPackage)) {
17103                     throw new SecurityException("Given caller package " + callerPackage
17104                             + " is not running in process " + callerApp);
17105                 }
17106                 callingUid = callerApp.info.uid;
17107                 callingPid = callerApp.pid;
17108             } else {
17109                 callerPackage = null;
17110                 callingUid = Binder.getCallingUid();
17111                 callingPid = Binder.getCallingPid();
17112             }
17113
17114             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17115                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17116
17117             Iterator<String> actions = filter.actionsIterator();
17118             if (actions == null) {
17119                 ArrayList<String> noAction = new ArrayList<String>(1);
17120                 noAction.add(null);
17121                 actions = noAction.iterator();
17122             }
17123
17124             // Collect stickies of users
17125             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17126             while (actions.hasNext()) {
17127                 String action = actions.next();
17128                 for (int id : userIds) {
17129                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17130                     if (stickies != null) {
17131                         ArrayList<Intent> intents = stickies.get(action);
17132                         if (intents != null) {
17133                             if (stickyIntents == null) {
17134                                 stickyIntents = new ArrayList<Intent>();
17135                             }
17136                             stickyIntents.addAll(intents);
17137                         }
17138                     }
17139                 }
17140             }
17141         }
17142
17143         ArrayList<Intent> allSticky = null;
17144         if (stickyIntents != null) {
17145             final ContentResolver resolver = mContext.getContentResolver();
17146             // Look for any matching sticky broadcasts...
17147             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17148                 Intent intent = stickyIntents.get(i);
17149                 // If intent has scheme "content", it will need to acccess
17150                 // provider that needs to lock mProviderMap in ActivityThread
17151                 // and also it may need to wait application response, so we
17152                 // cannot lock ActivityManagerService here.
17153                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17154                     if (allSticky == null) {
17155                         allSticky = new ArrayList<Intent>();
17156                     }
17157                     allSticky.add(intent);
17158                 }
17159             }
17160         }
17161
17162         // The first sticky in the list is returned directly back to the client.
17163         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17164         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17165         if (receiver == null) {
17166             return sticky;
17167         }
17168
17169         synchronized (this) {
17170             if (callerApp != null && (callerApp.thread == null
17171                     || callerApp.thread.asBinder() != caller.asBinder())) {
17172                 // Original caller already died
17173                 return null;
17174             }
17175             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17176             if (rl == null) {
17177                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17178                         userId, receiver);
17179                 if (rl.app != null) {
17180                     rl.app.receivers.add(rl);
17181                 } else {
17182                     try {
17183                         receiver.asBinder().linkToDeath(rl, 0);
17184                     } catch (RemoteException e) {
17185                         return sticky;
17186                     }
17187                     rl.linkedToDeath = true;
17188                 }
17189                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17190             } else if (rl.uid != callingUid) {
17191                 throw new IllegalArgumentException(
17192                         "Receiver requested to register for uid " + callingUid
17193                         + " was previously registered for uid " + rl.uid);
17194             } else if (rl.pid != callingPid) {
17195                 throw new IllegalArgumentException(
17196                         "Receiver requested to register for pid " + callingPid
17197                         + " was previously registered for pid " + rl.pid);
17198             } else if (rl.userId != userId) {
17199                 throw new IllegalArgumentException(
17200                         "Receiver requested to register for user " + userId
17201                         + " was previously registered for user " + rl.userId);
17202             }
17203             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17204                     permission, callingUid, userId);
17205             rl.add(bf);
17206             if (!bf.debugCheck()) {
17207                 Slog.w(TAG, "==> For Dynamic broadcast");
17208             }
17209             mReceiverResolver.addFilter(bf);
17210
17211             // Enqueue broadcasts for all existing stickies that match
17212             // this filter.
17213             if (allSticky != null) {
17214                 ArrayList receivers = new ArrayList();
17215                 receivers.add(bf);
17216
17217                 final int stickyCount = allSticky.size();
17218                 for (int i = 0; i < stickyCount; i++) {
17219                     Intent intent = allSticky.get(i);
17220                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17221                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17222                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17223                             null, 0, null, null, false, true, true, -1);
17224                     queue.enqueueParallelBroadcastLocked(r);
17225                     queue.scheduleBroadcastsLocked();
17226                 }
17227             }
17228
17229             return sticky;
17230         }
17231     }
17232
17233     public void unregisterReceiver(IIntentReceiver receiver) {
17234         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17235
17236         final long origId = Binder.clearCallingIdentity();
17237         try {
17238             boolean doTrim = false;
17239
17240             synchronized(this) {
17241                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17242                 if (rl != null) {
17243                     final BroadcastRecord r = rl.curBroadcast;
17244                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17245                         final boolean doNext = r.queue.finishReceiverLocked(
17246                                 r, r.resultCode, r.resultData, r.resultExtras,
17247                                 r.resultAbort, false);
17248                         if (doNext) {
17249                             doTrim = true;
17250                             r.queue.processNextBroadcast(false);
17251                         }
17252                     }
17253
17254                     if (rl.app != null) {
17255                         rl.app.receivers.remove(rl);
17256                     }
17257                     removeReceiverLocked(rl);
17258                     if (rl.linkedToDeath) {
17259                         rl.linkedToDeath = false;
17260                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17261                     }
17262                 }
17263             }
17264
17265             // If we actually concluded any broadcasts, we might now be able
17266             // to trim the recipients' apps from our working set
17267             if (doTrim) {
17268                 trimApplications();
17269                 return;
17270             }
17271
17272         } finally {
17273             Binder.restoreCallingIdentity(origId);
17274         }
17275     }
17276
17277     void removeReceiverLocked(ReceiverList rl) {
17278         mRegisteredReceivers.remove(rl.receiver.asBinder());
17279         for (int i = rl.size() - 1; i >= 0; i--) {
17280             mReceiverResolver.removeFilter(rl.get(i));
17281         }
17282     }
17283
17284     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17285         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17286             ProcessRecord r = mLruProcesses.get(i);
17287             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17288                 try {
17289                     r.thread.dispatchPackageBroadcast(cmd, packages);
17290                 } catch (RemoteException ex) {
17291                 }
17292             }
17293         }
17294     }
17295
17296     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17297             int callingUid, int[] users) {
17298         // TODO: come back and remove this assumption to triage all broadcasts
17299         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17300
17301         List<ResolveInfo> receivers = null;
17302         try {
17303             HashSet<ComponentName> singleUserReceivers = null;
17304             boolean scannedFirstReceivers = false;
17305             for (int user : users) {
17306                 // Skip users that have Shell restrictions, with exception of always permitted
17307                 // Shell broadcasts
17308                 if (callingUid == Process.SHELL_UID
17309                         && mUserController.hasUserRestriction(
17310                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17311                         && !isPermittedShellBroadcast(intent)) {
17312                     continue;
17313                 }
17314                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17315                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17316                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17317                     // If this is not the system user, we need to check for
17318                     // any receivers that should be filtered out.
17319                     for (int i=0; i<newReceivers.size(); i++) {
17320                         ResolveInfo ri = newReceivers.get(i);
17321                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17322                             newReceivers.remove(i);
17323                             i--;
17324                         }
17325                     }
17326                 }
17327                 if (newReceivers != null && newReceivers.size() == 0) {
17328                     newReceivers = null;
17329                 }
17330                 if (receivers == null) {
17331                     receivers = newReceivers;
17332                 } else if (newReceivers != null) {
17333                     // We need to concatenate the additional receivers
17334                     // found with what we have do far.  This would be easy,
17335                     // but we also need to de-dup any receivers that are
17336                     // singleUser.
17337                     if (!scannedFirstReceivers) {
17338                         // Collect any single user receivers we had already retrieved.
17339                         scannedFirstReceivers = true;
17340                         for (int i=0; i<receivers.size(); i++) {
17341                             ResolveInfo ri = receivers.get(i);
17342                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17343                                 ComponentName cn = new ComponentName(
17344                                         ri.activityInfo.packageName, ri.activityInfo.name);
17345                                 if (singleUserReceivers == null) {
17346                                     singleUserReceivers = new HashSet<ComponentName>();
17347                                 }
17348                                 singleUserReceivers.add(cn);
17349                             }
17350                         }
17351                     }
17352                     // Add the new results to the existing results, tracking
17353                     // and de-dupping single user receivers.
17354                     for (int i=0; i<newReceivers.size(); i++) {
17355                         ResolveInfo ri = newReceivers.get(i);
17356                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17357                             ComponentName cn = new ComponentName(
17358                                     ri.activityInfo.packageName, ri.activityInfo.name);
17359                             if (singleUserReceivers == null) {
17360                                 singleUserReceivers = new HashSet<ComponentName>();
17361                             }
17362                             if (!singleUserReceivers.contains(cn)) {
17363                                 singleUserReceivers.add(cn);
17364                                 receivers.add(ri);
17365                             }
17366                         } else {
17367                             receivers.add(ri);
17368                         }
17369                     }
17370                 }
17371             }
17372         } catch (RemoteException ex) {
17373             // pm is in same process, this will never happen.
17374         }
17375         return receivers;
17376     }
17377
17378     private boolean isPermittedShellBroadcast(Intent intent) {
17379         // remote bugreport should always be allowed to be taken
17380         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17381     }
17382
17383     final int broadcastIntentLocked(ProcessRecord callerApp,
17384             String callerPackage, Intent intent, String resolvedType,
17385             IIntentReceiver resultTo, int resultCode, String resultData,
17386             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17387             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17388         intent = new Intent(intent);
17389
17390         // By default broadcasts do not go to stopped apps.
17391         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17392
17393         // If we have not finished booting, don't allow this to launch new processes.
17394         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17395             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17396         }
17397
17398         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17399                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17400                 + " ordered=" + ordered + " userid=" + userId);
17401         if ((resultTo != null) && !ordered) {
17402             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17403         }
17404
17405         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17406                 ALLOW_NON_FULL, "broadcast", callerPackage);
17407
17408         // Make sure that the user who is receiving this broadcast is running.
17409         // If not, we will just skip it. Make an exception for shutdown broadcasts
17410         // and upgrade steps.
17411
17412         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17413             if ((callingUid != Process.SYSTEM_UID
17414                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17415                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17416                 Slog.w(TAG, "Skipping broadcast of " + intent
17417                         + ": user " + userId + " is stopped");
17418                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17419             }
17420         }
17421
17422         BroadcastOptions brOptions = null;
17423         if (bOptions != null) {
17424             brOptions = new BroadcastOptions(bOptions);
17425             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17426                 // See if the caller is allowed to do this.  Note we are checking against
17427                 // the actual real caller (not whoever provided the operation as say a
17428                 // PendingIntent), because that who is actually supplied the arguments.
17429                 if (checkComponentPermission(
17430                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17431                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17432                         != PackageManager.PERMISSION_GRANTED) {
17433                     String msg = "Permission Denial: " + intent.getAction()
17434                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17435                             + ", uid=" + callingUid + ")"
17436                             + " requires "
17437                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17438                     Slog.w(TAG, msg);
17439                     throw new SecurityException(msg);
17440                 }
17441             }
17442         }
17443
17444         // Verify that protected broadcasts are only being sent by system code,
17445         // and that system code is only sending protected broadcasts.
17446         final String action = intent.getAction();
17447         final boolean isProtectedBroadcast;
17448         try {
17449             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17450         } catch (RemoteException e) {
17451             Slog.w(TAG, "Remote exception", e);
17452             return ActivityManager.BROADCAST_SUCCESS;
17453         }
17454
17455         final boolean isCallerSystem;
17456         switch (UserHandle.getAppId(callingUid)) {
17457             case Process.ROOT_UID:
17458             case Process.SYSTEM_UID:
17459             case Process.PHONE_UID:
17460             case Process.BLUETOOTH_UID:
17461             case Process.NFC_UID:
17462                 isCallerSystem = true;
17463                 break;
17464             default:
17465                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17466                 break;
17467         }
17468
17469         if (isCallerSystem) {
17470             if (isProtectedBroadcast
17471                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17472                     || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17473                     || Intent.ACTION_MEDIA_BUTTON.equals(action)
17474                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17475                     || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17476                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17477                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17478                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17479                     || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17480                     || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17481                 // Broadcast is either protected, or it's a public action that
17482                 // we've relaxed, so it's fine for system internals to send.
17483             } else {
17484                 // The vast majority of broadcasts sent from system internals
17485                 // should be protected to avoid security holes, so yell loudly
17486                 // to ensure we examine these cases.
17487                 if (callerApp != null) {
17488                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17489                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17490                             new Throwable());
17491                 } else {
17492                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17493                             + " from system uid " + UserHandle.formatUid(callingUid)
17494                             + " pkg " + callerPackage,
17495                             new Throwable());
17496                 }
17497             }
17498
17499         } else {
17500             if (isProtectedBroadcast) {
17501                 String msg = "Permission Denial: not allowed to send broadcast "
17502                         + action + " from pid="
17503                         + callingPid + ", uid=" + callingUid;
17504                 Slog.w(TAG, msg);
17505                 throw new SecurityException(msg);
17506
17507             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17508                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17509                 // Special case for compatibility: we don't want apps to send this,
17510                 // but historically it has not been protected and apps may be using it
17511                 // to poke their own app widget.  So, instead of making it protected,
17512                 // just limit it to the caller.
17513                 if (callerPackage == null) {
17514                     String msg = "Permission Denial: not allowed to send broadcast "
17515                             + action + " from unknown caller.";
17516                     Slog.w(TAG, msg);
17517                     throw new SecurityException(msg);
17518                 } else if (intent.getComponent() != null) {
17519                     // They are good enough to send to an explicit component...  verify
17520                     // it is being sent to the calling app.
17521                     if (!intent.getComponent().getPackageName().equals(
17522                             callerPackage)) {
17523                         String msg = "Permission Denial: not allowed to send broadcast "
17524                                 + action + " to "
17525                                 + intent.getComponent().getPackageName() + " from "
17526                                 + callerPackage;
17527                         Slog.w(TAG, msg);
17528                         throw new SecurityException(msg);
17529                     }
17530                 } else {
17531                     // Limit broadcast to their own package.
17532                     intent.setPackage(callerPackage);
17533                 }
17534             }
17535         }
17536
17537         if (action != null) {
17538             switch (action) {
17539                 case Intent.ACTION_UID_REMOVED:
17540                 case Intent.ACTION_PACKAGE_REMOVED:
17541                 case Intent.ACTION_PACKAGE_CHANGED:
17542                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17543                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17544                 case Intent.ACTION_PACKAGES_SUSPENDED:
17545                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17546                     // Handle special intents: if this broadcast is from the package
17547                     // manager about a package being removed, we need to remove all of
17548                     // its activities from the history stack.
17549                     if (checkComponentPermission(
17550                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17551                             callingPid, callingUid, -1, true)
17552                             != PackageManager.PERMISSION_GRANTED) {
17553                         String msg = "Permission Denial: " + intent.getAction()
17554                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17555                                 + ", uid=" + callingUid + ")"
17556                                 + " requires "
17557                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17558                         Slog.w(TAG, msg);
17559                         throw new SecurityException(msg);
17560                     }
17561                     switch (action) {
17562                         case Intent.ACTION_UID_REMOVED:
17563                             final Bundle intentExtras = intent.getExtras();
17564                             final int uid = intentExtras != null
17565                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17566                             if (uid >= 0) {
17567                                 mBatteryStatsService.removeUid(uid);
17568                                 mAppOpsService.uidRemoved(uid);
17569                             }
17570                             break;
17571                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17572                             // If resources are unavailable just force stop all those packages
17573                             // and flush the attribute cache as well.
17574                             String list[] =
17575                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17576                             if (list != null && list.length > 0) {
17577                                 for (int i = 0; i < list.length; i++) {
17578                                     forceStopPackageLocked(list[i], -1, false, true, true,
17579                                             false, false, userId, "storage unmount");
17580                                 }
17581                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17582                                 sendPackageBroadcastLocked(
17583                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17584                                         userId);
17585                             }
17586                             break;
17587                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17588                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17589                             break;
17590                         case Intent.ACTION_PACKAGE_REMOVED:
17591                         case Intent.ACTION_PACKAGE_CHANGED:
17592                             Uri data = intent.getData();
17593                             String ssp;
17594                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17595                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17596                                 final boolean replacing =
17597                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17598                                 final boolean killProcess =
17599                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17600                                 final boolean fullUninstall = removed && !replacing;
17601                                 if (removed) {
17602                                     if (killProcess) {
17603                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
17604                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17605                                                 false, true, true, false, fullUninstall, userId,
17606                                                 removed ? "pkg removed" : "pkg changed");
17607                                     }
17608                                     final int cmd = killProcess
17609                                             ? IApplicationThread.PACKAGE_REMOVED
17610                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17611                                     sendPackageBroadcastLocked(cmd,
17612                                             new String[] {ssp}, userId);
17613                                     if (fullUninstall) {
17614                                         mAppOpsService.packageRemoved(
17615                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17616
17617                                         // Remove all permissions granted from/to this package
17618                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
17619
17620                                         removeTasksByPackageNameLocked(ssp, userId);
17621                                         mBatteryStatsService.notePackageUninstalled(ssp);
17622                                     }
17623                                 } else {
17624                                     if (killProcess) {
17625                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
17626                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17627                                                 userId, ProcessList.INVALID_ADJ,
17628                                                 false, true, true, false, "change " + ssp);
17629                                     }
17630                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17631                                             intent.getStringArrayExtra(
17632                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17633                                 }
17634                             }
17635                             break;
17636                         case Intent.ACTION_PACKAGES_SUSPENDED:
17637                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
17638                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17639                                     intent.getAction());
17640                             final String[] packageNames = intent.getStringArrayExtra(
17641                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
17642                             final int userHandle = intent.getIntExtra(
17643                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17644
17645                             synchronized(ActivityManagerService.this) {
17646                                 mRecentTasks.onPackagesSuspendedChanged(
17647                                         packageNames, suspended, userHandle);
17648                             }
17649                             break;
17650                     }
17651                     break;
17652                 case Intent.ACTION_PACKAGE_REPLACED:
17653                 {
17654                     final Uri data = intent.getData();
17655                     final String ssp;
17656                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17657                         final ApplicationInfo aInfo =
17658                                 getPackageManagerInternalLocked().getApplicationInfo(
17659                                         ssp,
17660                                         userId);
17661                         if (aInfo == null) {
17662                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17663                                     + " ssp=" + ssp + " data=" + data);
17664                             return ActivityManager.BROADCAST_SUCCESS;
17665                         }
17666                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17667                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17668                                 new String[] {ssp}, userId);
17669                     }
17670                     break;
17671                 }
17672                 case Intent.ACTION_PACKAGE_ADDED:
17673                 {
17674                     // Special case for adding a package: by default turn on compatibility mode.
17675                     Uri data = intent.getData();
17676                     String ssp;
17677                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17678                         final boolean replacing =
17679                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17680                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17681
17682                         try {
17683                             ApplicationInfo ai = AppGlobals.getPackageManager().
17684                                     getApplicationInfo(ssp, 0, 0);
17685                             mBatteryStatsService.notePackageInstalled(ssp,
17686                                     ai != null ? ai.versionCode : 0);
17687                         } catch (RemoteException e) {
17688                         }
17689                     }
17690                     break;
17691                 }
17692                 case Intent.ACTION_TIMEZONE_CHANGED:
17693                     // If this is the time zone changed action, queue up a message that will reset
17694                     // the timezone of all currently running processes. This message will get
17695                     // queued up before the broadcast happens.
17696                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17697                     break;
17698                 case Intent.ACTION_TIME_CHANGED:
17699                     // If the user set the time, let all running processes know.
17700                     final int is24Hour =
17701                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17702                                     : 0;
17703                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17704                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17705                     synchronized (stats) {
17706                         stats.noteCurrentTimeChangedLocked();
17707                     }
17708                     break;
17709                 case Intent.ACTION_CLEAR_DNS_CACHE:
17710                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17711                     break;
17712                 case Proxy.PROXY_CHANGE_ACTION:
17713                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17714                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17715                     break;
17716                 case android.hardware.Camera.ACTION_NEW_PICTURE:
17717                 case android.hardware.Camera.ACTION_NEW_VIDEO:
17718                     // These broadcasts are no longer allowed by the system, since they can
17719                     // cause significant thrashing at a crictical point (using the camera).
17720                     // Apps should use JobScehduler to monitor for media provider changes.
17721                     Slog.w(TAG, action + " no longer allowed; dropping from "
17722                             + UserHandle.formatUid(callingUid));
17723                     // Lie; we don't want to crash the app.
17724                     return ActivityManager.BROADCAST_SUCCESS;
17725             }
17726         }
17727
17728         // Add to the sticky list if requested.
17729         if (sticky) {
17730             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17731                     callingPid, callingUid)
17732                     != PackageManager.PERMISSION_GRANTED) {
17733                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17734                         + callingPid + ", uid=" + callingUid
17735                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17736                 Slog.w(TAG, msg);
17737                 throw new SecurityException(msg);
17738             }
17739             if (requiredPermissions != null && requiredPermissions.length > 0) {
17740                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17741                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
17742                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17743             }
17744             if (intent.getComponent() != null) {
17745                 throw new SecurityException(
17746                         "Sticky broadcasts can't target a specific component");
17747             }
17748             // We use userId directly here, since the "all" target is maintained
17749             // as a separate set of sticky broadcasts.
17750             if (userId != UserHandle.USER_ALL) {
17751                 // But first, if this is not a broadcast to all users, then
17752                 // make sure it doesn't conflict with an existing broadcast to
17753                 // all users.
17754                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17755                         UserHandle.USER_ALL);
17756                 if (stickies != null) {
17757                     ArrayList<Intent> list = stickies.get(intent.getAction());
17758                     if (list != null) {
17759                         int N = list.size();
17760                         int i;
17761                         for (i=0; i<N; i++) {
17762                             if (intent.filterEquals(list.get(i))) {
17763                                 throw new IllegalArgumentException(
17764                                         "Sticky broadcast " + intent + " for user "
17765                                         + userId + " conflicts with existing global broadcast");
17766                             }
17767                         }
17768                     }
17769                 }
17770             }
17771             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17772             if (stickies == null) {
17773                 stickies = new ArrayMap<>();
17774                 mStickyBroadcasts.put(userId, stickies);
17775             }
17776             ArrayList<Intent> list = stickies.get(intent.getAction());
17777             if (list == null) {
17778                 list = new ArrayList<>();
17779                 stickies.put(intent.getAction(), list);
17780             }
17781             final int stickiesCount = list.size();
17782             int i;
17783             for (i = 0; i < stickiesCount; i++) {
17784                 if (intent.filterEquals(list.get(i))) {
17785                     // This sticky already exists, replace it.
17786                     list.set(i, new Intent(intent));
17787                     break;
17788                 }
17789             }
17790             if (i >= stickiesCount) {
17791                 list.add(new Intent(intent));
17792             }
17793         }
17794
17795         int[] users;
17796         if (userId == UserHandle.USER_ALL) {
17797             // Caller wants broadcast to go to all started users.
17798             users = mUserController.getStartedUserArrayLocked();
17799         } else {
17800             // Caller wants broadcast to go to one specific user.
17801             users = new int[] {userId};
17802         }
17803
17804         // Figure out who all will receive this broadcast.
17805         List receivers = null;
17806         List<BroadcastFilter> registeredReceivers = null;
17807         // Need to resolve the intent to interested receivers...
17808         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17809                  == 0) {
17810             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17811         }
17812         if (intent.getComponent() == null) {
17813             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17814                 // Query one target user at a time, excluding shell-restricted users
17815                 for (int i = 0; i < users.length; i++) {
17816                     if (mUserController.hasUserRestriction(
17817                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17818                         continue;
17819                     }
17820                     List<BroadcastFilter> registeredReceiversForUser =
17821                             mReceiverResolver.queryIntent(intent,
17822                                     resolvedType, false, users[i]);
17823                     if (registeredReceivers == null) {
17824                         registeredReceivers = registeredReceiversForUser;
17825                     } else if (registeredReceiversForUser != null) {
17826                         registeredReceivers.addAll(registeredReceiversForUser);
17827                     }
17828                 }
17829             } else {
17830                 registeredReceivers = mReceiverResolver.queryIntent(intent,
17831                         resolvedType, false, userId);
17832             }
17833         }
17834
17835         final boolean replacePending =
17836                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17837
17838         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17839                 + " replacePending=" + replacePending);
17840
17841         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17842         if (!ordered && NR > 0) {
17843             // If we are not serializing this broadcast, then send the
17844             // registered receivers separately so they don't wait for the
17845             // components to be launched.
17846             final BroadcastQueue queue = broadcastQueueForIntent(intent);
17847             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17848                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17849                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17850                     resultExtras, ordered, sticky, false, userId);
17851             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17852             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17853             if (!replaced) {
17854                 queue.enqueueParallelBroadcastLocked(r);
17855                 queue.scheduleBroadcastsLocked();
17856             }
17857             registeredReceivers = null;
17858             NR = 0;
17859         }
17860
17861         // Merge into one list.
17862         int ir = 0;
17863         if (receivers != null) {
17864             // A special case for PACKAGE_ADDED: do not allow the package
17865             // being added to see this broadcast.  This prevents them from
17866             // using this as a back door to get run as soon as they are
17867             // installed.  Maybe in the future we want to have a special install
17868             // broadcast or such for apps, but we'd like to deliberately make
17869             // this decision.
17870             String skipPackages[] = null;
17871             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17872                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17873                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17874                 Uri data = intent.getData();
17875                 if (data != null) {
17876                     String pkgName = data.getSchemeSpecificPart();
17877                     if (pkgName != null) {
17878                         skipPackages = new String[] { pkgName };
17879                     }
17880                 }
17881             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17882                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17883             }
17884             if (skipPackages != null && (skipPackages.length > 0)) {
17885                 for (String skipPackage : skipPackages) {
17886                     if (skipPackage != null) {
17887                         int NT = receivers.size();
17888                         for (int it=0; it<NT; it++) {
17889                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
17890                             if (curt.activityInfo.packageName.equals(skipPackage)) {
17891                                 receivers.remove(it);
17892                                 it--;
17893                                 NT--;
17894                             }
17895                         }
17896                     }
17897                 }
17898             }
17899
17900             int NT = receivers != null ? receivers.size() : 0;
17901             int it = 0;
17902             ResolveInfo curt = null;
17903             BroadcastFilter curr = null;
17904             while (it < NT && ir < NR) {
17905                 if (curt == null) {
17906                     curt = (ResolveInfo)receivers.get(it);
17907                 }
17908                 if (curr == null) {
17909                     curr = registeredReceivers.get(ir);
17910                 }
17911                 if (curr.getPriority() >= curt.priority) {
17912                     // Insert this broadcast record into the final list.
17913                     receivers.add(it, curr);
17914                     ir++;
17915                     curr = null;
17916                     it++;
17917                     NT++;
17918                 } else {
17919                     // Skip to the next ResolveInfo in the final list.
17920                     it++;
17921                     curt = null;
17922                 }
17923             }
17924         }
17925         while (ir < NR) {
17926             if (receivers == null) {
17927                 receivers = new ArrayList();
17928             }
17929             receivers.add(registeredReceivers.get(ir));
17930             ir++;
17931         }
17932
17933         if ((receivers != null && receivers.size() > 0)
17934                 || resultTo != null) {
17935             BroadcastQueue queue = broadcastQueueForIntent(intent);
17936             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17937                     callerPackage, callingPid, callingUid, resolvedType,
17938                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17939                     resultData, resultExtras, ordered, sticky, false, userId);
17940
17941             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17942                     + ": prev had " + queue.mOrderedBroadcasts.size());
17943             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17944                     "Enqueueing broadcast " + r.intent.getAction());
17945
17946             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17947             if (!replaced) {
17948                 queue.enqueueOrderedBroadcastLocked(r);
17949                 queue.scheduleBroadcastsLocked();
17950             }
17951         }
17952
17953         return ActivityManager.BROADCAST_SUCCESS;
17954     }
17955
17956     final Intent verifyBroadcastLocked(Intent intent) {
17957         // Refuse possible leaked file descriptors
17958         if (intent != null && intent.hasFileDescriptors() == true) {
17959             throw new IllegalArgumentException("File descriptors passed in Intent");
17960         }
17961
17962         int flags = intent.getFlags();
17963
17964         if (!mProcessesReady) {
17965             // if the caller really truly claims to know what they're doing, go
17966             // ahead and allow the broadcast without launching any receivers
17967             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17968                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17969             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17970                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17971                         + " before boot completion");
17972                 throw new IllegalStateException("Cannot broadcast before boot completed");
17973             }
17974         }
17975
17976         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17977             throw new IllegalArgumentException(
17978                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17979         }
17980
17981         return intent;
17982     }
17983
17984     public final int broadcastIntent(IApplicationThread caller,
17985             Intent intent, String resolvedType, IIntentReceiver resultTo,
17986             int resultCode, String resultData, Bundle resultExtras,
17987             String[] requiredPermissions, int appOp, Bundle bOptions,
17988             boolean serialized, boolean sticky, int userId) {
17989         enforceNotIsolatedCaller("broadcastIntent");
17990         synchronized(this) {
17991             intent = verifyBroadcastLocked(intent);
17992
17993             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17994             final int callingPid = Binder.getCallingPid();
17995             final int callingUid = Binder.getCallingUid();
17996             final long origId = Binder.clearCallingIdentity();
17997             int res = broadcastIntentLocked(callerApp,
17998                     callerApp != null ? callerApp.info.packageName : null,
17999                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18000                     requiredPermissions, appOp, bOptions, serialized, sticky,
18001                     callingPid, callingUid, userId);
18002             Binder.restoreCallingIdentity(origId);
18003             return res;
18004         }
18005     }
18006
18007
18008     int broadcastIntentInPackage(String packageName, int uid,
18009             Intent intent, String resolvedType, IIntentReceiver resultTo,
18010             int resultCode, String resultData, Bundle resultExtras,
18011             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18012             int userId) {
18013         synchronized(this) {
18014             intent = verifyBroadcastLocked(intent);
18015
18016             final long origId = Binder.clearCallingIdentity();
18017             String[] requiredPermissions = requiredPermission == null ? null
18018                     : new String[] {requiredPermission};
18019             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18020                     resultTo, resultCode, resultData, resultExtras,
18021                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18022                     sticky, -1, uid, userId);
18023             Binder.restoreCallingIdentity(origId);
18024             return res;
18025         }
18026     }
18027
18028     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18029         // Refuse possible leaked file descriptors
18030         if (intent != null && intent.hasFileDescriptors() == true) {
18031             throw new IllegalArgumentException("File descriptors passed in Intent");
18032         }
18033
18034         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18035                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18036
18037         synchronized(this) {
18038             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18039                     != PackageManager.PERMISSION_GRANTED) {
18040                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18041                         + Binder.getCallingPid()
18042                         + ", uid=" + Binder.getCallingUid()
18043                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18044                 Slog.w(TAG, msg);
18045                 throw new SecurityException(msg);
18046             }
18047             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18048             if (stickies != null) {
18049                 ArrayList<Intent> list = stickies.get(intent.getAction());
18050                 if (list != null) {
18051                     int N = list.size();
18052                     int i;
18053                     for (i=0; i<N; i++) {
18054                         if (intent.filterEquals(list.get(i))) {
18055                             list.remove(i);
18056                             break;
18057                         }
18058                     }
18059                     if (list.size() <= 0) {
18060                         stickies.remove(intent.getAction());
18061                     }
18062                 }
18063                 if (stickies.size() <= 0) {
18064                     mStickyBroadcasts.remove(userId);
18065                 }
18066             }
18067         }
18068     }
18069
18070     void backgroundServicesFinishedLocked(int userId) {
18071         for (BroadcastQueue queue : mBroadcastQueues) {
18072             queue.backgroundServicesFinishedLocked(userId);
18073         }
18074     }
18075
18076     public void finishReceiver(IBinder who, int resultCode, String resultData,
18077             Bundle resultExtras, boolean resultAbort, int flags) {
18078         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18079
18080         // Refuse possible leaked file descriptors
18081         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18082             throw new IllegalArgumentException("File descriptors passed in Bundle");
18083         }
18084
18085         final long origId = Binder.clearCallingIdentity();
18086         try {
18087             boolean doNext = false;
18088             BroadcastRecord r;
18089
18090             synchronized(this) {
18091                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18092                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18093                 r = queue.getMatchingOrderedReceiver(who);
18094                 if (r != null) {
18095                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18096                         resultData, resultExtras, resultAbort, true);
18097                 }
18098             }
18099
18100             if (doNext) {
18101                 r.queue.processNextBroadcast(false);
18102             }
18103             trimApplications();
18104         } finally {
18105             Binder.restoreCallingIdentity(origId);
18106         }
18107     }
18108
18109     // =========================================================
18110     // INSTRUMENTATION
18111     // =========================================================
18112
18113     public boolean startInstrumentation(ComponentName className,
18114             String profileFile, int flags, Bundle arguments,
18115             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18116             int userId, String abiOverride) {
18117         enforceNotIsolatedCaller("startInstrumentation");
18118         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18119                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18120         // Refuse possible leaked file descriptors
18121         if (arguments != null && arguments.hasFileDescriptors()) {
18122             throw new IllegalArgumentException("File descriptors passed in Bundle");
18123         }
18124
18125         synchronized(this) {
18126             InstrumentationInfo ii = null;
18127             ApplicationInfo ai = null;
18128             try {
18129                 ii = mContext.getPackageManager().getInstrumentationInfo(
18130                     className, STOCK_PM_FLAGS);
18131                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18132                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18133             } catch (PackageManager.NameNotFoundException e) {
18134             } catch (RemoteException e) {
18135             }
18136             if (ii == null) {
18137                 reportStartInstrumentationFailureLocked(watcher, className,
18138                         "Unable to find instrumentation info for: " + className);
18139                 return false;
18140             }
18141             if (ai == null) {
18142                 reportStartInstrumentationFailureLocked(watcher, className,
18143                         "Unable to find instrumentation target package: " + ii.targetPackage);
18144                 return false;
18145             }
18146             if (!ai.hasCode()) {
18147                 reportStartInstrumentationFailureLocked(watcher, className,
18148                         "Instrumentation target has no code: " + ii.targetPackage);
18149                 return false;
18150             }
18151
18152             int match = mContext.getPackageManager().checkSignatures(
18153                     ii.targetPackage, ii.packageName);
18154             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18155                 String msg = "Permission Denial: starting instrumentation "
18156                         + className + " from pid="
18157                         + Binder.getCallingPid()
18158                         + ", uid=" + Binder.getCallingPid()
18159                         + " not allowed because package " + ii.packageName
18160                         + " does not have a signature matching the target "
18161                         + ii.targetPackage;
18162                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18163                 throw new SecurityException(msg);
18164             }
18165
18166             final long origId = Binder.clearCallingIdentity();
18167             // Instrumentation can kill and relaunch even persistent processes
18168             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18169                     "start instr");
18170             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18171             app.instrumentationClass = className;
18172             app.instrumentationInfo = ai;
18173             app.instrumentationProfileFile = profileFile;
18174             app.instrumentationArguments = arguments;
18175             app.instrumentationWatcher = watcher;
18176             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18177             app.instrumentationResultClass = className;
18178             Binder.restoreCallingIdentity(origId);
18179         }
18180
18181         return true;
18182     }
18183
18184     /**
18185      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18186      * error to the logs, but if somebody is watching, send the report there too.  This enables
18187      * the "am" command to report errors with more information.
18188      *
18189      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18190      * @param cn The component name of the instrumentation.
18191      * @param report The error report.
18192      */
18193     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18194             ComponentName cn, String report) {
18195         Slog.w(TAG, report);
18196         if (watcher != null) {
18197             Bundle results = new Bundle();
18198             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18199             results.putString("Error", report);
18200             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18201         }
18202     }
18203
18204     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18205         if (app.instrumentationWatcher != null) {
18206             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18207                     app.instrumentationClass, resultCode, results);
18208         }
18209
18210         // Can't call out of the system process with a lock held, so post a message.
18211         if (app.instrumentationUiAutomationConnection != null) {
18212             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18213                     app.instrumentationUiAutomationConnection).sendToTarget();
18214         }
18215
18216         app.instrumentationWatcher = null;
18217         app.instrumentationUiAutomationConnection = null;
18218         app.instrumentationClass = null;
18219         app.instrumentationInfo = null;
18220         app.instrumentationProfileFile = null;
18221         app.instrumentationArguments = null;
18222
18223         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18224                 "finished inst");
18225     }
18226
18227     public void finishInstrumentation(IApplicationThread target,
18228             int resultCode, Bundle results) {
18229         int userId = UserHandle.getCallingUserId();
18230         // Refuse possible leaked file descriptors
18231         if (results != null && results.hasFileDescriptors()) {
18232             throw new IllegalArgumentException("File descriptors passed in Intent");
18233         }
18234
18235         synchronized(this) {
18236             ProcessRecord app = getRecordForAppLocked(target);
18237             if (app == null) {
18238                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18239                 return;
18240             }
18241             final long origId = Binder.clearCallingIdentity();
18242             finishInstrumentationLocked(app, resultCode, results);
18243             Binder.restoreCallingIdentity(origId);
18244         }
18245     }
18246
18247     // =========================================================
18248     // CONFIGURATION
18249     // =========================================================
18250
18251     public ConfigurationInfo getDeviceConfigurationInfo() {
18252         ConfigurationInfo config = new ConfigurationInfo();
18253         synchronized (this) {
18254             config.reqTouchScreen = mConfiguration.touchscreen;
18255             config.reqKeyboardType = mConfiguration.keyboard;
18256             config.reqNavigation = mConfiguration.navigation;
18257             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18258                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18259                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18260             }
18261             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18262                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18263                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18264             }
18265             config.reqGlEsVersion = GL_ES_VERSION;
18266         }
18267         return config;
18268     }
18269
18270     ActivityStack getFocusedStack() {
18271         return mStackSupervisor.getFocusedStack();
18272     }
18273
18274     @Override
18275     public int getFocusedStackId() throws RemoteException {
18276         ActivityStack focusedStack = getFocusedStack();
18277         if (focusedStack != null) {
18278             return focusedStack.getStackId();
18279         }
18280         return -1;
18281     }
18282
18283     public Configuration getConfiguration() {
18284         Configuration ci;
18285         synchronized(this) {
18286             ci = new Configuration(mConfiguration);
18287             ci.userSetLocale = false;
18288         }
18289         return ci;
18290     }
18291
18292     @Override
18293     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18294         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18295         synchronized (this) {
18296             mSuppressResizeConfigChanges = suppress;
18297         }
18298     }
18299
18300     @Override
18301     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18302         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18303         if (fromStackId == HOME_STACK_ID) {
18304             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18305         }
18306         synchronized (this) {
18307             final long origId = Binder.clearCallingIdentity();
18308             try {
18309                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18310             } finally {
18311                 Binder.restoreCallingIdentity(origId);
18312             }
18313         }
18314     }
18315
18316     @Override
18317     public void updatePersistentConfiguration(Configuration values) {
18318         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319                 "updateConfiguration()");
18320         enforceWriteSettingsPermission("updateConfiguration()");
18321         if (values == null) {
18322             throw new NullPointerException("Configuration must not be null");
18323         }
18324
18325         int userId = UserHandle.getCallingUserId();
18326
18327         synchronized(this) {
18328             final long origId = Binder.clearCallingIdentity();
18329             updateConfigurationLocked(values, null, false, true, userId);
18330             Binder.restoreCallingIdentity(origId);
18331         }
18332     }
18333
18334     private void updateFontScaleIfNeeded() {
18335         final int currentUserId;
18336         synchronized(this) {
18337             currentUserId = mUserController.getCurrentUserIdLocked();
18338         }
18339         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18340                 FONT_SCALE, 1.0f, currentUserId);
18341         if (mConfiguration.fontScale != scaleFactor) {
18342             final Configuration configuration = mWindowManager.computeNewConfiguration();
18343             configuration.fontScale = scaleFactor;
18344             updatePersistentConfiguration(configuration);
18345         }
18346     }
18347
18348     private void enforceWriteSettingsPermission(String func) {
18349         int uid = Binder.getCallingUid();
18350         if (uid == Process.ROOT_UID) {
18351             return;
18352         }
18353
18354         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18355                 Settings.getPackageNameForUid(mContext, uid), false)) {
18356             return;
18357         }
18358
18359         String msg = "Permission Denial: " + func + " from pid="
18360                 + Binder.getCallingPid()
18361                 + ", uid=" + uid
18362                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18363         Slog.w(TAG, msg);
18364         throw new SecurityException(msg);
18365     }
18366
18367     public void updateConfiguration(Configuration values) {
18368         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18369                 "updateConfiguration()");
18370
18371         synchronized(this) {
18372             if (values == null && mWindowManager != null) {
18373                 // sentinel: fetch the current configuration from the window manager
18374                 values = mWindowManager.computeNewConfiguration();
18375             }
18376
18377             if (mWindowManager != null) {
18378                 mProcessList.applyDisplaySize(mWindowManager);
18379             }
18380
18381             final long origId = Binder.clearCallingIdentity();
18382             if (values != null) {
18383                 Settings.System.clearConfiguration(values);
18384             }
18385             updateConfigurationLocked(values, null, false);
18386             Binder.restoreCallingIdentity(origId);
18387         }
18388     }
18389
18390     void updateUserConfigurationLocked() {
18391         Configuration configuration = new Configuration(mConfiguration);
18392         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18393                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18394         updateConfigurationLocked(configuration, null, false);
18395     }
18396
18397     boolean updateConfigurationLocked(Configuration values,
18398             ActivityRecord starting, boolean initLocale) {
18399         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18400         return updateConfigurationLocked(values, starting, initLocale, false,
18401                 UserHandle.USER_NULL);
18402     }
18403
18404     // To cache the list of supported system locales
18405     private String[] mSupportedSystemLocales = null;
18406
18407     /**
18408      * Do either or both things: (1) change the current configuration, and (2)
18409      * make sure the given activity is running with the (now) current
18410      * configuration.  Returns true if the activity has been left running, or
18411      * false if <var>starting</var> is being destroyed to match the new
18412      * configuration.
18413      *
18414      * @param userId is only used when persistent parameter is set to true to persist configuration
18415      *               for that particular user
18416      */
18417     private boolean updateConfigurationLocked(Configuration values,
18418             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18419         int changes = 0;
18420
18421         if (mWindowManager != null) {
18422             mWindowManager.deferSurfaceLayout();
18423         }
18424         if (values != null) {
18425             Configuration newConfig = new Configuration(mConfiguration);
18426             changes = newConfig.updateFrom(values);
18427             if (changes != 0) {
18428                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18429                         "Updating configuration to: " + values);
18430
18431                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18432
18433                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18434                     final LocaleList locales = values.getLocales();
18435                     int bestLocaleIndex = 0;
18436                     if (locales.size() > 1) {
18437                         if (mSupportedSystemLocales == null) {
18438                             mSupportedSystemLocales =
18439                                     Resources.getSystem().getAssets().getLocales();
18440                         }
18441                         bestLocaleIndex = Math.max(0,
18442                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
18443                     }
18444                     SystemProperties.set("persist.sys.locale",
18445                             locales.get(bestLocaleIndex).toLanguageTag());
18446                     LocaleList.setDefault(locales, bestLocaleIndex);
18447                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18448                             locales.get(bestLocaleIndex)));
18449                 }
18450
18451                 mConfigurationSeq++;
18452                 if (mConfigurationSeq <= 0) {
18453                     mConfigurationSeq = 1;
18454                 }
18455                 newConfig.seq = mConfigurationSeq;
18456                 mConfiguration = newConfig;
18457                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18458                 mUsageStatsService.reportConfigurationChange(newConfig,
18459                         mUserController.getCurrentUserIdLocked());
18460                 //mUsageStatsService.noteStartConfig(newConfig);
18461
18462                 final Configuration configCopy = new Configuration(mConfiguration);
18463
18464                 // TODO: If our config changes, should we auto dismiss any currently
18465                 // showing dialogs?
18466                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18467
18468                 AttributeCache ac = AttributeCache.instance();
18469                 if (ac != null) {
18470                     ac.updateConfiguration(configCopy);
18471                 }
18472
18473                 // Make sure all resources in our process are updated
18474                 // right now, so that anyone who is going to retrieve
18475                 // resource values after we return will be sure to get
18476                 // the new ones.  This is especially important during
18477                 // boot, where the first config change needs to guarantee
18478                 // all resources have that config before following boot
18479                 // code is executed.
18480                 mSystemThread.applyConfigurationToResources(configCopy);
18481
18482                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18483                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18484                     msg.obj = new Configuration(configCopy);
18485                     msg.arg1 = userId;
18486                     mHandler.sendMessage(msg);
18487                 }
18488
18489                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18490                 if (isDensityChange) {
18491                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18492                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18493                 }
18494
18495                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18496                     ProcessRecord app = mLruProcesses.get(i);
18497                     try {
18498                         if (app.thread != null) {
18499                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18500                                     + app.processName + " new config " + mConfiguration);
18501                             app.thread.scheduleConfigurationChanged(configCopy);
18502                         }
18503                     } catch (Exception e) {
18504                     }
18505                 }
18506                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18507                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18508                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
18509                         | Intent.FLAG_RECEIVER_FOREGROUND);
18510                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18511                         null, AppOpsManager.OP_NONE, null, false, false,
18512                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18513                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18514                     // Tell the shortcut manager that the system locale changed.  It needs to know
18515                     // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18516                     // we "push" from here, rather than having the service listen to the broadcast.
18517                     final ShortcutServiceInternal shortcutService =
18518                             LocalServices.getService(ShortcutServiceInternal.class);
18519                     if (shortcutService != null) {
18520                         shortcutService.onSystemLocaleChangedNoLock();
18521                     }
18522
18523                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18524                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18525                     if (!mProcessesReady) {
18526                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18527                     }
18528                     broadcastIntentLocked(null, null, intent,
18529                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18530                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18531                 }
18532             }
18533             // Update the configuration with WM first and check if any of the stacks need to be
18534             // resized due to the configuration change. If so, resize the stacks now and do any
18535             // relaunches if necessary. This way we don't need to relaunch again below in
18536             // ensureActivityConfigurationLocked().
18537             if (mWindowManager != null) {
18538                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18539                 if (resizedStacks != null) {
18540                     for (int stackId : resizedStacks) {
18541                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18542                         mStackSupervisor.resizeStackLocked(
18543                                 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18544                     }
18545                 }
18546             }
18547         }
18548
18549         boolean kept = true;
18550         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18551         // mainStack is null during startup.
18552         if (mainStack != null) {
18553             if (changes != 0 && starting == null) {
18554                 // If the configuration changed, and the caller is not already
18555                 // in the process of starting an activity, then find the top
18556                 // activity to check if its configuration needs to change.
18557                 starting = mainStack.topRunningActivityLocked();
18558             }
18559
18560             if (starting != null) {
18561                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18562                 // And we need to make sure at this point that all other activities
18563                 // are made visible with the correct configuration.
18564                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18565                         !PRESERVE_WINDOWS);
18566             }
18567         }
18568         if (mWindowManager != null) {
18569             mWindowManager.continueSurfaceLayout();
18570         }
18571         return kept;
18572     }
18573
18574     /**
18575      * Decide based on the configuration whether we should shouw the ANR,
18576      * crash, etc dialogs.  The idea is that if there is no affordnace to
18577      * press the on-screen buttons, we shouldn't show the dialog.
18578      *
18579      * A thought: SystemUI might also want to get told about this, the Power
18580      * dialog / global actions also might want different behaviors.
18581      */
18582     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18583         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18584                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18585                                    && config.navigation == Configuration.NAVIGATION_NONAV);
18586         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18587                                     == Configuration.UI_MODE_TYPE_CAR);
18588         return inputMethodExists && uiIsNotCarType && !inVrMode;
18589     }
18590
18591     @Override
18592     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18593         synchronized (this) {
18594             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18595             if (srec != null) {
18596                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18597             }
18598         }
18599         return false;
18600     }
18601
18602     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18603             Intent resultData) {
18604
18605         synchronized (this) {
18606             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18607             if (r != null) {
18608                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18609             }
18610             return false;
18611         }
18612     }
18613
18614     public int getLaunchedFromUid(IBinder activityToken) {
18615         ActivityRecord srec;
18616         synchronized (this) {
18617             srec = ActivityRecord.forTokenLocked(activityToken);
18618         }
18619         if (srec == null) {
18620             return -1;
18621         }
18622         return srec.launchedFromUid;
18623     }
18624
18625     public String getLaunchedFromPackage(IBinder activityToken) {
18626         ActivityRecord srec;
18627         synchronized (this) {
18628             srec = ActivityRecord.forTokenLocked(activityToken);
18629         }
18630         if (srec == null) {
18631             return null;
18632         }
18633         return srec.launchedFromPackage;
18634     }
18635
18636     // =========================================================
18637     // LIFETIME MANAGEMENT
18638     // =========================================================
18639
18640     // Returns which broadcast queue the app is the current [or imminent] receiver
18641     // on, or 'null' if the app is not an active broadcast recipient.
18642     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18643         BroadcastRecord r = app.curReceiver;
18644         if (r != null) {
18645             return r.queue;
18646         }
18647
18648         // It's not the current receiver, but it might be starting up to become one
18649         synchronized (this) {
18650             for (BroadcastQueue queue : mBroadcastQueues) {
18651                 r = queue.mPendingBroadcast;
18652                 if (r != null && r.curApp == app) {
18653                     // found it; report which queue it's in
18654                     return queue;
18655                 }
18656             }
18657         }
18658
18659         return null;
18660     }
18661
18662     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18663             int targetUid, ComponentName targetComponent, String targetProcess) {
18664         if (!mTrackingAssociations) {
18665             return null;
18666         }
18667         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18668                 = mAssociations.get(targetUid);
18669         if (components == null) {
18670             components = new ArrayMap<>();
18671             mAssociations.put(targetUid, components);
18672         }
18673         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18674         if (sourceUids == null) {
18675             sourceUids = new SparseArray<>();
18676             components.put(targetComponent, sourceUids);
18677         }
18678         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18679         if (sourceProcesses == null) {
18680             sourceProcesses = new ArrayMap<>();
18681             sourceUids.put(sourceUid, sourceProcesses);
18682         }
18683         Association ass = sourceProcesses.get(sourceProcess);
18684         if (ass == null) {
18685             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18686                     targetProcess);
18687             sourceProcesses.put(sourceProcess, ass);
18688         }
18689         ass.mCount++;
18690         ass.mNesting++;
18691         if (ass.mNesting == 1) {
18692             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18693             ass.mLastState = sourceState;
18694         }
18695         return ass;
18696     }
18697
18698     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18699             ComponentName targetComponent) {
18700         if (!mTrackingAssociations) {
18701             return;
18702         }
18703         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18704                 = mAssociations.get(targetUid);
18705         if (components == null) {
18706             return;
18707         }
18708         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18709         if (sourceUids == null) {
18710             return;
18711         }
18712         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18713         if (sourceProcesses == null) {
18714             return;
18715         }
18716         Association ass = sourceProcesses.get(sourceProcess);
18717         if (ass == null || ass.mNesting <= 0) {
18718             return;
18719         }
18720         ass.mNesting--;
18721         if (ass.mNesting == 0) {
18722             long uptime = SystemClock.uptimeMillis();
18723             ass.mTime += uptime - ass.mStartTime;
18724             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18725                     += uptime - ass.mLastStateUptime;
18726             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18727         }
18728     }
18729
18730     private void noteUidProcessState(final int uid, final int state) {
18731         mBatteryStatsService.noteUidProcessState(uid, state);
18732         if (mTrackingAssociations) {
18733             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18734                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18735                         = mAssociations.valueAt(i1);
18736                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18737                     SparseArray<ArrayMap<String, Association>> sourceUids
18738                             = targetComponents.valueAt(i2);
18739                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18740                     if (sourceProcesses != null) {
18741                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18742                             Association ass = sourceProcesses.valueAt(i4);
18743                             if (ass.mNesting >= 1) {
18744                                 // currently associated
18745                                 long uptime = SystemClock.uptimeMillis();
18746                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18747                                         += uptime - ass.mLastStateUptime;
18748                                 ass.mLastState = state;
18749                                 ass.mLastStateUptime = uptime;
18750                             }
18751                         }
18752                     }
18753                 }
18754             }
18755         }
18756     }
18757
18758     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18759             boolean doingAll, long now) {
18760         if (mAdjSeq == app.adjSeq) {
18761             // This adjustment has already been computed.
18762             return app.curRawAdj;
18763         }
18764
18765         if (app.thread == null) {
18766             app.adjSeq = mAdjSeq;
18767             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18768             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18769             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18770         }
18771
18772         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18773         app.adjSource = null;
18774         app.adjTarget = null;
18775         app.empty = false;
18776         app.cached = false;
18777
18778         final int activitiesSize = app.activities.size();
18779
18780         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18781             // The max adjustment doesn't allow this app to be anything
18782             // below foreground, so it is not worth doing work for it.
18783             app.adjType = "fixed";
18784             app.adjSeq = mAdjSeq;
18785             app.curRawAdj = app.maxAdj;
18786             app.foregroundActivities = false;
18787             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18788             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18789             // System processes can do UI, and when they do we want to have
18790             // them trim their memory after the user leaves the UI.  To
18791             // facilitate this, here we need to determine whether or not it
18792             // is currently showing UI.
18793             app.systemNoUi = true;
18794             if (app == TOP_APP) {
18795                 app.systemNoUi = false;
18796                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18797                 app.adjType = "pers-top-activity";
18798             } else if (activitiesSize > 0) {
18799                 for (int j = 0; j < activitiesSize; j++) {
18800                     final ActivityRecord r = app.activities.get(j);
18801                     if (r.visible) {
18802                         app.systemNoUi = false;
18803                     }
18804                 }
18805             }
18806             if (!app.systemNoUi) {
18807                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18808             }
18809             return (app.curAdj=app.maxAdj);
18810         }
18811
18812         app.systemNoUi = false;
18813
18814         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18815
18816         // Determine the importance of the process, starting with most
18817         // important to least, and assign an appropriate OOM adjustment.
18818         int adj;
18819         int schedGroup;
18820         int procState;
18821         boolean foregroundActivities = false;
18822         BroadcastQueue queue;
18823         if (app == TOP_APP) {
18824             // The last app on the list is the foreground app.
18825             adj = ProcessList.FOREGROUND_APP_ADJ;
18826             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18827             app.adjType = "top-activity";
18828             foregroundActivities = true;
18829             procState = PROCESS_STATE_CUR_TOP;
18830         } else if (app.instrumentationClass != null) {
18831             // Don't want to kill running instrumentation.
18832             adj = ProcessList.FOREGROUND_APP_ADJ;
18833             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18834             app.adjType = "instrumentation";
18835             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18836         } else if ((queue = isReceivingBroadcast(app)) != null) {
18837             // An app that is currently receiving a broadcast also
18838             // counts as being in the foreground for OOM killer purposes.
18839             // It's placed in a sched group based on the nature of the
18840             // broadcast as reflected by which queue it's active in.
18841             adj = ProcessList.FOREGROUND_APP_ADJ;
18842             schedGroup = (queue == mFgBroadcastQueue)
18843                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18844             app.adjType = "broadcast";
18845             procState = ActivityManager.PROCESS_STATE_RECEIVER;
18846         } else if (app.executingServices.size() > 0) {
18847             // An app that is currently executing a service callback also
18848             // counts as being in the foreground.
18849             adj = ProcessList.FOREGROUND_APP_ADJ;
18850             schedGroup = app.execServicesFg ?
18851                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18852             app.adjType = "exec-service";
18853             procState = ActivityManager.PROCESS_STATE_SERVICE;
18854             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18855         } else {
18856             // As far as we know the process is empty.  We may change our mind later.
18857             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18858             // At this point we don't actually know the adjustment.  Use the cached adj
18859             // value that the caller wants us to.
18860             adj = cachedAdj;
18861             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18862             app.cached = true;
18863             app.empty = true;
18864             app.adjType = "cch-empty";
18865         }
18866
18867         // Examine all activities if not already foreground.
18868         if (!foregroundActivities && activitiesSize > 0) {
18869             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18870             for (int j = 0; j < activitiesSize; j++) {
18871                 final ActivityRecord r = app.activities.get(j);
18872                 if (r.app != app) {
18873                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
18874                             + " instead of expected " + app);
18875                     if (r.app == null || (r.app.uid == app.uid)) {
18876                         // Only fix things up when they look sane
18877                         r.app = app;
18878                     } else {
18879                         continue;
18880                     }
18881                 }
18882                 if (r.visible) {
18883                     // App has a visible activity; only upgrade adjustment.
18884                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18885                         adj = ProcessList.VISIBLE_APP_ADJ;
18886                         app.adjType = "visible";
18887                     }
18888                     if (procState > PROCESS_STATE_CUR_TOP) {
18889                         procState = PROCESS_STATE_CUR_TOP;
18890                     }
18891                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18892                     app.cached = false;
18893                     app.empty = false;
18894                     foregroundActivities = true;
18895                     if (r.task != null && minLayer > 0) {
18896                         final int layer = r.task.mLayerRank;
18897                         if (layer >= 0 && minLayer > layer) {
18898                             minLayer = layer;
18899                         }
18900                     }
18901                     break;
18902                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18903                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18904                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18905                         app.adjType = "pausing";
18906                     }
18907                     if (procState > PROCESS_STATE_CUR_TOP) {
18908                         procState = PROCESS_STATE_CUR_TOP;
18909                     }
18910                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18911                     app.cached = false;
18912                     app.empty = false;
18913                     foregroundActivities = true;
18914                 } else if (r.state == ActivityState.STOPPING) {
18915                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18916                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18917                         app.adjType = "stopping";
18918                     }
18919                     // For the process state, we will at this point consider the
18920                     // process to be cached.  It will be cached either as an activity
18921                     // or empty depending on whether the activity is finishing.  We do
18922                     // this so that we can treat the process as cached for purposes of
18923                     // memory trimming (determing current memory level, trim command to
18924                     // send to process) since there can be an arbitrary number of stopping
18925                     // processes and they should soon all go into the cached state.
18926                     if (!r.finishing) {
18927                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18928                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18929                         }
18930                     }
18931                     app.cached = false;
18932                     app.empty = false;
18933                     foregroundActivities = true;
18934                 } else {
18935                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18936                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18937                         app.adjType = "cch-act";
18938                     }
18939                 }
18940             }
18941             if (adj == ProcessList.VISIBLE_APP_ADJ) {
18942                 adj += minLayer;
18943             }
18944         }
18945
18946         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18947                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18948             if (app.foregroundServices) {
18949                 // The user is aware of this app, so make it visible.
18950                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18951                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18952                 app.cached = false;
18953                 app.adjType = "fg-service";
18954                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18955             } else if (app.forcingToForeground != null) {
18956                 // The user is aware of this app, so make it visible.
18957                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18958                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18959                 app.cached = false;
18960                 app.adjType = "force-fg";
18961                 app.adjSource = app.forcingToForeground;
18962                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18963             }
18964         }
18965
18966         if (app == mHeavyWeightProcess) {
18967             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18968                 // We don't want to kill the current heavy-weight process.
18969                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18970                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18971                 app.cached = false;
18972                 app.adjType = "heavy";
18973             }
18974             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18975                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18976             }
18977         }
18978
18979         if (app == mHomeProcess) {
18980             if (adj > ProcessList.HOME_APP_ADJ) {
18981                 // This process is hosting what we currently consider to be the
18982                 // home app, so we don't want to let it go into the background.
18983                 adj = ProcessList.HOME_APP_ADJ;
18984                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18985                 app.cached = false;
18986                 app.adjType = "home";
18987             }
18988             if (procState > ActivityManager.PROCESS_STATE_HOME) {
18989                 procState = ActivityManager.PROCESS_STATE_HOME;
18990             }
18991         }
18992
18993         if (app == mPreviousProcess && app.activities.size() > 0) {
18994             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18995                 // This was the previous process that showed UI to the user.
18996                 // We want to try to keep it around more aggressively, to give
18997                 // a good experience around switching between two apps.
18998                 adj = ProcessList.PREVIOUS_APP_ADJ;
18999                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19000                 app.cached = false;
19001                 app.adjType = "previous";
19002             }
19003             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19004                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19005             }
19006         }
19007
19008         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19009                 + " reason=" + app.adjType);
19010
19011         // By default, we use the computed adjustment.  It may be changed if
19012         // there are applications dependent on our services or providers, but
19013         // this gives us a baseline and makes sure we don't get into an
19014         // infinite recursion.
19015         app.adjSeq = mAdjSeq;
19016         app.curRawAdj = adj;
19017         app.hasStartedServices = false;
19018
19019         if (mBackupTarget != null && app == mBackupTarget.app) {
19020             // If possible we want to avoid killing apps while they're being backed up
19021             if (adj > ProcessList.BACKUP_APP_ADJ) {
19022                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19023                 adj = ProcessList.BACKUP_APP_ADJ;
19024                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19025                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19026                 }
19027                 app.adjType = "backup";
19028                 app.cached = false;
19029             }
19030             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19031                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19032             }
19033         }
19034
19035         boolean mayBeTop = false;
19036
19037         for (int is = app.services.size()-1;
19038                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19039                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19040                         || procState > ActivityManager.PROCESS_STATE_TOP);
19041                 is--) {
19042             ServiceRecord s = app.services.valueAt(is);
19043             if (s.startRequested) {
19044                 app.hasStartedServices = true;
19045                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19046                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19047                 }
19048                 if (app.hasShownUi && app != mHomeProcess) {
19049                     // If this process has shown some UI, let it immediately
19050                     // go to the LRU list because it may be pretty heavy with
19051                     // UI stuff.  We'll tag it with a label just to help
19052                     // debug and understand what is going on.
19053                     if (adj > ProcessList.SERVICE_ADJ) {
19054                         app.adjType = "cch-started-ui-services";
19055                     }
19056                 } else {
19057                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19058                         // This service has seen some activity within
19059                         // recent memory, so we will keep its process ahead
19060                         // of the background processes.
19061                         if (adj > ProcessList.SERVICE_ADJ) {
19062                             adj = ProcessList.SERVICE_ADJ;
19063                             app.adjType = "started-services";
19064                             app.cached = false;
19065                         }
19066                     }
19067                     // If we have let the service slide into the background
19068                     // state, still have some text describing what it is doing
19069                     // even though the service no longer has an impact.
19070                     if (adj > ProcessList.SERVICE_ADJ) {
19071                         app.adjType = "cch-started-services";
19072                     }
19073                 }
19074             }
19075
19076             app.whitelistManager = false;
19077
19078             for (int conni = s.connections.size()-1;
19079                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19080                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19081                             || procState > ActivityManager.PROCESS_STATE_TOP);
19082                     conni--) {
19083                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19084                 for (int i = 0;
19085                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19086                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19087                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19088                         i++) {
19089                     // XXX should compute this based on the max of
19090                     // all connected clients.
19091                     ConnectionRecord cr = clist.get(i);
19092                     if (cr.binding.client == app) {
19093                         // Binding to ourself is not interesting.
19094                         continue;
19095                     }
19096                     if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19097                         app.whitelistManager = true;
19098                     }
19099
19100                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19101                         ProcessRecord client = cr.binding.client;
19102                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19103                                 TOP_APP, doingAll, now);
19104                         int clientProcState = client.curProcState;
19105                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19106                             // If the other app is cached for any reason, for purposes here
19107                             // we are going to consider it empty.  The specific cached state
19108                             // doesn't propagate except under certain conditions.
19109                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19110                         }
19111                         String adjType = null;
19112                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19113                             // Not doing bind OOM management, so treat
19114                             // this guy more like a started service.
19115                             if (app.hasShownUi && app != mHomeProcess) {
19116                                 // If this process has shown some UI, let it immediately
19117                                 // go to the LRU list because it may be pretty heavy with
19118                                 // UI stuff.  We'll tag it with a label just to help
19119                                 // debug and understand what is going on.
19120                                 if (adj > clientAdj) {
19121                                     adjType = "cch-bound-ui-services";
19122                                 }
19123                                 app.cached = false;
19124                                 clientAdj = adj;
19125                                 clientProcState = procState;
19126                             } else {
19127                                 if (now >= (s.lastActivity
19128                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19129                                     // This service has not seen activity within
19130                                     // recent memory, so allow it to drop to the
19131                                     // LRU list if there is no other reason to keep
19132                                     // it around.  We'll also tag it with a label just
19133                                     // to help debug and undertand what is going on.
19134                                     if (adj > clientAdj) {
19135                                         adjType = "cch-bound-services";
19136                                     }
19137                                     clientAdj = adj;
19138                                 }
19139                             }
19140                         }
19141                         if (adj > clientAdj) {
19142                             // If this process has recently shown UI, and
19143                             // the process that is binding to it is less
19144                             // important than being visible, then we don't
19145                             // care about the binding as much as we care
19146                             // about letting this process get into the LRU
19147                             // list to be killed and restarted if needed for
19148                             // memory.
19149                             if (app.hasShownUi && app != mHomeProcess
19150                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19151                                 adjType = "cch-bound-ui-services";
19152                             } else {
19153                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19154                                         |Context.BIND_IMPORTANT)) != 0) {
19155                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19156                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19157                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19158                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19159                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19160                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19161                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19162                                     adj = clientAdj;
19163                                 } else {
19164                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19165                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19166                                     }
19167                                 }
19168                                 if (!client.cached) {
19169                                     app.cached = false;
19170                                 }
19171                                 adjType = "service";
19172                             }
19173                         }
19174                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19175                             // This will treat important bound services identically to
19176                             // the top app, which may behave differently than generic
19177                             // foreground work.
19178                             if (client.curSchedGroup > schedGroup) {
19179                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19180                                     schedGroup = client.curSchedGroup;
19181                                 } else {
19182                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19183                                 }
19184                             }
19185                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19186                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19187                                     // Special handling of clients who are in the top state.
19188                                     // We *may* want to consider this process to be in the
19189                                     // top state as well, but only if there is not another
19190                                     // reason for it to be running.  Being on the top is a
19191                                     // special state, meaning you are specifically running
19192                                     // for the current top app.  If the process is already
19193                                     // running in the background for some other reason, it
19194                                     // is more important to continue considering it to be
19195                                     // in the background state.
19196                                     mayBeTop = true;
19197                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19198                                 } else {
19199                                     // Special handling for above-top states (persistent
19200                                     // processes).  These should not bring the current process
19201                                     // into the top state, since they are not on top.  Instead
19202                                     // give them the best state after that.
19203                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19204                                         clientProcState =
19205                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19206                                     } else if (mWakefulness
19207                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19208                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19209                                                     != 0) {
19210                                         clientProcState =
19211                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19212                                     } else {
19213                                         clientProcState =
19214                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19215                                     }
19216                                 }
19217                             }
19218                         } else {
19219                             if (clientProcState <
19220                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19221                                 clientProcState =
19222                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19223                             }
19224                         }
19225                         if (procState > clientProcState) {
19226                             procState = clientProcState;
19227                         }
19228                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19229                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19230                             app.pendingUiClean = true;
19231                         }
19232                         if (adjType != null) {
19233                             app.adjType = adjType;
19234                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19235                                     .REASON_SERVICE_IN_USE;
19236                             app.adjSource = cr.binding.client;
19237                             app.adjSourceProcState = clientProcState;
19238                             app.adjTarget = s.name;
19239                         }
19240                     }
19241                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19242                         app.treatLikeActivity = true;
19243                     }
19244                     final ActivityRecord a = cr.activity;
19245                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19246                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19247                             (a.visible || a.state == ActivityState.RESUMED ||
19248                              a.state == ActivityState.PAUSING)) {
19249                             adj = ProcessList.FOREGROUND_APP_ADJ;
19250                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19251                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19252                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19253                                 } else {
19254                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19255                                 }
19256                             }
19257                             app.cached = false;
19258                             app.adjType = "service";
19259                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19260                                     .REASON_SERVICE_IN_USE;
19261                             app.adjSource = a;
19262                             app.adjSourceProcState = procState;
19263                             app.adjTarget = s.name;
19264                         }
19265                     }
19266                 }
19267             }
19268         }
19269
19270         for (int provi = app.pubProviders.size()-1;
19271                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19272                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19273                         || procState > ActivityManager.PROCESS_STATE_TOP);
19274                 provi--) {
19275             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19276             for (int i = cpr.connections.size()-1;
19277                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19278                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19279                             || procState > ActivityManager.PROCESS_STATE_TOP);
19280                     i--) {
19281                 ContentProviderConnection conn = cpr.connections.get(i);
19282                 ProcessRecord client = conn.client;
19283                 if (client == app) {
19284                     // Being our own client is not interesting.
19285                     continue;
19286                 }
19287                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19288                 int clientProcState = client.curProcState;
19289                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19290                     // If the other app is cached for any reason, for purposes here
19291                     // we are going to consider it empty.
19292                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19293                 }
19294                 if (adj > clientAdj) {
19295                     if (app.hasShownUi && app != mHomeProcess
19296                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19297                         app.adjType = "cch-ui-provider";
19298                     } else {
19299                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19300                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19301                         app.adjType = "provider";
19302                     }
19303                     app.cached &= client.cached;
19304                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19305                             .REASON_PROVIDER_IN_USE;
19306                     app.adjSource = client;
19307                     app.adjSourceProcState = clientProcState;
19308                     app.adjTarget = cpr.name;
19309                 }
19310                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19311                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19312                         // Special handling of clients who are in the top state.
19313                         // We *may* want to consider this process to be in the
19314                         // top state as well, but only if there is not another
19315                         // reason for it to be running.  Being on the top is a
19316                         // special state, meaning you are specifically running
19317                         // for the current top app.  If the process is already
19318                         // running in the background for some other reason, it
19319                         // is more important to continue considering it to be
19320                         // in the background state.
19321                         mayBeTop = true;
19322                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19323                     } else {
19324                         // Special handling for above-top states (persistent
19325                         // processes).  These should not bring the current process
19326                         // into the top state, since they are not on top.  Instead
19327                         // give them the best state after that.
19328                         clientProcState =
19329                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19330                     }
19331                 }
19332                 if (procState > clientProcState) {
19333                     procState = clientProcState;
19334                 }
19335                 if (client.curSchedGroup > schedGroup) {
19336                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19337                 }
19338             }
19339             // If the provider has external (non-framework) process
19340             // dependencies, ensure that its adjustment is at least
19341             // FOREGROUND_APP_ADJ.
19342             if (cpr.hasExternalProcessHandles()) {
19343                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19344                     adj = ProcessList.FOREGROUND_APP_ADJ;
19345                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19346                     app.cached = false;
19347                     app.adjType = "provider";
19348                     app.adjTarget = cpr.name;
19349                 }
19350                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19351                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19352                 }
19353             }
19354         }
19355
19356         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19357             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19358                 adj = ProcessList.PREVIOUS_APP_ADJ;
19359                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19360                 app.cached = false;
19361                 app.adjType = "provider";
19362             }
19363             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19364                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19365             }
19366         }
19367
19368         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19369             // A client of one of our services or providers is in the top state.  We
19370             // *may* want to be in the top state, but not if we are already running in
19371             // the background for some other reason.  For the decision here, we are going
19372             // to pick out a few specific states that we want to remain in when a client
19373             // is top (states that tend to be longer-term) and otherwise allow it to go
19374             // to the top state.
19375             switch (procState) {
19376                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19377                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19378                 case ActivityManager.PROCESS_STATE_SERVICE:
19379                     // These all are longer-term states, so pull them up to the top
19380                     // of the background states, but not all the way to the top state.
19381                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19382                     break;
19383                 default:
19384                     // Otherwise, top is a better choice, so take it.
19385                     procState = ActivityManager.PROCESS_STATE_TOP;
19386                     break;
19387             }
19388         }
19389
19390         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19391             if (app.hasClientActivities) {
19392                 // This is a cached process, but with client activities.  Mark it so.
19393                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19394                 app.adjType = "cch-client-act";
19395             } else if (app.treatLikeActivity) {
19396                 // This is a cached process, but somebody wants us to treat it like it has
19397                 // an activity, okay!
19398                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19399                 app.adjType = "cch-as-act";
19400             }
19401         }
19402
19403         if (adj == ProcessList.SERVICE_ADJ) {
19404             if (doingAll) {
19405                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19406                 mNewNumServiceProcs++;
19407                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19408                 if (!app.serviceb) {
19409                     // This service isn't far enough down on the LRU list to
19410                     // normally be a B service, but if we are low on RAM and it
19411                     // is large we want to force it down since we would prefer to
19412                     // keep launcher over it.
19413                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19414                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19415                         app.serviceHighRam = true;
19416                         app.serviceb = true;
19417                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19418                     } else {
19419                         mNewNumAServiceProcs++;
19420                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19421                     }
19422                 } else {
19423                     app.serviceHighRam = false;
19424                 }
19425             }
19426             if (app.serviceb) {
19427                 adj = ProcessList.SERVICE_B_ADJ;
19428             }
19429         }
19430
19431         app.curRawAdj = adj;
19432
19433         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19434         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19435         if (adj > app.maxAdj) {
19436             adj = app.maxAdj;
19437             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19438                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19439             }
19440         }
19441
19442         // Do final modification to adj.  Everything we do between here and applying
19443         // the final setAdj must be done in this function, because we will also use
19444         // it when computing the final cached adj later.  Note that we don't need to
19445         // worry about this for max adj above, since max adj will always be used to
19446         // keep it out of the cached vaues.
19447         app.curAdj = app.modifyRawOomAdj(adj);
19448         app.curSchedGroup = schedGroup;
19449         app.curProcState = procState;
19450         app.foregroundActivities = foregroundActivities;
19451
19452         return app.curRawAdj;
19453     }
19454
19455     /**
19456      * Record new PSS sample for a process.
19457      */
19458     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19459             long now) {
19460         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19461                 swapPss * 1024);
19462         proc.lastPssTime = now;
19463         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19464         if (DEBUG_PSS) Slog.d(TAG_PSS,
19465                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19466                 + " state=" + ProcessList.makeProcStateString(procState));
19467         if (proc.initialIdlePss == 0) {
19468             proc.initialIdlePss = pss;
19469         }
19470         proc.lastPss = pss;
19471         proc.lastSwapPss = swapPss;
19472         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19473             proc.lastCachedPss = pss;
19474             proc.lastCachedSwapPss = swapPss;
19475         }
19476
19477         final SparseArray<Pair<Long, String>> watchUids
19478                 = mMemWatchProcesses.getMap().get(proc.processName);
19479         Long check = null;
19480         if (watchUids != null) {
19481             Pair<Long, String> val = watchUids.get(proc.uid);
19482             if (val == null) {
19483                 val = watchUids.get(0);
19484             }
19485             if (val != null) {
19486                 check = val.first;
19487             }
19488         }
19489         if (check != null) {
19490             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19491                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19492                 if (!isDebuggable) {
19493                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19494                         isDebuggable = true;
19495                     }
19496                 }
19497                 if (isDebuggable) {
19498                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19499                     final ProcessRecord myProc = proc;
19500                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
19501                     mMemWatchDumpProcName = proc.processName;
19502                     mMemWatchDumpFile = heapdumpFile.toString();
19503                     mMemWatchDumpPid = proc.pid;
19504                     mMemWatchDumpUid = proc.uid;
19505                     BackgroundThread.getHandler().post(new Runnable() {
19506                         @Override
19507                         public void run() {
19508                             revokeUriPermission(ActivityThread.currentActivityThread()
19509                                             .getApplicationThread(),
19510                                     DumpHeapActivity.JAVA_URI,
19511                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
19512                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19513                                     UserHandle.myUserId());
19514                             ParcelFileDescriptor fd = null;
19515                             try {
19516                                 heapdumpFile.delete();
19517                                 fd = ParcelFileDescriptor.open(heapdumpFile,
19518                                         ParcelFileDescriptor.MODE_CREATE |
19519                                                 ParcelFileDescriptor.MODE_TRUNCATE |
19520                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
19521                                                 ParcelFileDescriptor.MODE_APPEND);
19522                                 IApplicationThread thread = myProc.thread;
19523                                 if (thread != null) {
19524                                     try {
19525                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
19526                                                 "Requesting dump heap from "
19527                                                 + myProc + " to " + heapdumpFile);
19528                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
19529                                     } catch (RemoteException e) {
19530                                     }
19531                                 }
19532                             } catch (FileNotFoundException e) {
19533                                 e.printStackTrace();
19534                             } finally {
19535                                 if (fd != null) {
19536                                     try {
19537                                         fd.close();
19538                                     } catch (IOException e) {
19539                                     }
19540                                 }
19541                             }
19542                         }
19543                     });
19544                 } else {
19545                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19546                             + ", but debugging not enabled");
19547                 }
19548             }
19549         }
19550     }
19551
19552     /**
19553      * Schedule PSS collection of a process.
19554      */
19555     void requestPssLocked(ProcessRecord proc, int procState) {
19556         if (mPendingPssProcesses.contains(proc)) {
19557             return;
19558         }
19559         if (mPendingPssProcesses.size() == 0) {
19560             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19561         }
19562         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19563         proc.pssProcState = procState;
19564         mPendingPssProcesses.add(proc);
19565     }
19566
19567     /**
19568      * Schedule PSS collection of all processes.
19569      */
19570     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19571         if (!always) {
19572             if (now < (mLastFullPssTime +
19573                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19574                 return;
19575             }
19576         }
19577         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19578         mLastFullPssTime = now;
19579         mFullPssPending = true;
19580         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19581         mPendingPssProcesses.clear();
19582         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19583             ProcessRecord app = mLruProcesses.get(i);
19584             if (app.thread == null
19585                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19586                 continue;
19587             }
19588             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19589                 app.pssProcState = app.setProcState;
19590                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19591                         mTestPssMode, isSleeping(), now);
19592                 mPendingPssProcesses.add(app);
19593             }
19594         }
19595         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19596     }
19597
19598     public void setTestPssMode(boolean enabled) {
19599         synchronized (this) {
19600             mTestPssMode = enabled;
19601             if (enabled) {
19602                 // Whenever we enable the mode, we want to take a snapshot all of current
19603                 // process mem use.
19604                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19605             }
19606         }
19607     }
19608
19609     /**
19610      * Ask a given process to GC right now.
19611      */
19612     final void performAppGcLocked(ProcessRecord app) {
19613         try {
19614             app.lastRequestedGc = SystemClock.uptimeMillis();
19615             if (app.thread != null) {
19616                 if (app.reportLowMemory) {
19617                     app.reportLowMemory = false;
19618                     app.thread.scheduleLowMemory();
19619                 } else {
19620                     app.thread.processInBackground();
19621                 }
19622             }
19623         } catch (Exception e) {
19624             // whatever.
19625         }
19626     }
19627
19628     /**
19629      * Returns true if things are idle enough to perform GCs.
19630      */
19631     private final boolean canGcNowLocked() {
19632         boolean processingBroadcasts = false;
19633         for (BroadcastQueue q : mBroadcastQueues) {
19634             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19635                 processingBroadcasts = true;
19636             }
19637         }
19638         return !processingBroadcasts
19639                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19640     }
19641
19642     /**
19643      * Perform GCs on all processes that are waiting for it, but only
19644      * if things are idle.
19645      */
19646     final void performAppGcsLocked() {
19647         final int N = mProcessesToGc.size();
19648         if (N <= 0) {
19649             return;
19650         }
19651         if (canGcNowLocked()) {
19652             while (mProcessesToGc.size() > 0) {
19653                 ProcessRecord proc = mProcessesToGc.remove(0);
19654                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19655                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19656                             <= SystemClock.uptimeMillis()) {
19657                         // To avoid spamming the system, we will GC processes one
19658                         // at a time, waiting a few seconds between each.
19659                         performAppGcLocked(proc);
19660                         scheduleAppGcsLocked();
19661                         return;
19662                     } else {
19663                         // It hasn't been long enough since we last GCed this
19664                         // process...  put it in the list to wait for its time.
19665                         addProcessToGcListLocked(proc);
19666                         break;
19667                     }
19668                 }
19669             }
19670
19671             scheduleAppGcsLocked();
19672         }
19673     }
19674
19675     /**
19676      * If all looks good, perform GCs on all processes waiting for them.
19677      */
19678     final void performAppGcsIfAppropriateLocked() {
19679         if (canGcNowLocked()) {
19680             performAppGcsLocked();
19681             return;
19682         }
19683         // Still not idle, wait some more.
19684         scheduleAppGcsLocked();
19685     }
19686
19687     /**
19688      * Schedule the execution of all pending app GCs.
19689      */
19690     final void scheduleAppGcsLocked() {
19691         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19692
19693         if (mProcessesToGc.size() > 0) {
19694             // Schedule a GC for the time to the next process.
19695             ProcessRecord proc = mProcessesToGc.get(0);
19696             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19697
19698             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19699             long now = SystemClock.uptimeMillis();
19700             if (when < (now+GC_TIMEOUT)) {
19701                 when = now + GC_TIMEOUT;
19702             }
19703             mHandler.sendMessageAtTime(msg, when);
19704         }
19705     }
19706
19707     /**
19708      * Add a process to the array of processes waiting to be GCed.  Keeps the
19709      * list in sorted order by the last GC time.  The process can't already be
19710      * on the list.
19711      */
19712     final void addProcessToGcListLocked(ProcessRecord proc) {
19713         boolean added = false;
19714         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19715             if (mProcessesToGc.get(i).lastRequestedGc <
19716                     proc.lastRequestedGc) {
19717                 added = true;
19718                 mProcessesToGc.add(i+1, proc);
19719                 break;
19720             }
19721         }
19722         if (!added) {
19723             mProcessesToGc.add(0, proc);
19724         }
19725     }
19726
19727     /**
19728      * Set up to ask a process to GC itself.  This will either do it
19729      * immediately, or put it on the list of processes to gc the next
19730      * time things are idle.
19731      */
19732     final void scheduleAppGcLocked(ProcessRecord app) {
19733         long now = SystemClock.uptimeMillis();
19734         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19735             return;
19736         }
19737         if (!mProcessesToGc.contains(app)) {
19738             addProcessToGcListLocked(app);
19739             scheduleAppGcsLocked();
19740         }
19741     }
19742
19743     final void checkExcessivePowerUsageLocked(boolean doKills) {
19744         updateCpuStatsNow();
19745
19746         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19747         boolean doWakeKills = doKills;
19748         boolean doCpuKills = doKills;
19749         if (mLastPowerCheckRealtime == 0) {
19750             doWakeKills = false;
19751         }
19752         if (mLastPowerCheckUptime == 0) {
19753             doCpuKills = false;
19754         }
19755         if (stats.isScreenOn()) {
19756             doWakeKills = false;
19757         }
19758         final long curRealtime = SystemClock.elapsedRealtime();
19759         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19760         final long curUptime = SystemClock.uptimeMillis();
19761         final long uptimeSince = curUptime - mLastPowerCheckUptime;
19762         mLastPowerCheckRealtime = curRealtime;
19763         mLastPowerCheckUptime = curUptime;
19764         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19765             doWakeKills = false;
19766         }
19767         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19768             doCpuKills = false;
19769         }
19770         int i = mLruProcesses.size();
19771         while (i > 0) {
19772             i--;
19773             ProcessRecord app = mLruProcesses.get(i);
19774             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19775                 long wtime;
19776                 synchronized (stats) {
19777                     wtime = stats.getProcessWakeTime(app.info.uid,
19778                             app.pid, curRealtime);
19779                 }
19780                 long wtimeUsed = wtime - app.lastWakeTime;
19781                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19782                 if (DEBUG_POWER) {
19783                     StringBuilder sb = new StringBuilder(128);
19784                     sb.append("Wake for ");
19785                     app.toShortString(sb);
19786                     sb.append(": over ");
19787                     TimeUtils.formatDuration(realtimeSince, sb);
19788                     sb.append(" used ");
19789                     TimeUtils.formatDuration(wtimeUsed, sb);
19790                     sb.append(" (");
19791                     sb.append((wtimeUsed*100)/realtimeSince);
19792                     sb.append("%)");
19793                     Slog.i(TAG_POWER, sb.toString());
19794                     sb.setLength(0);
19795                     sb.append("CPU for ");
19796                     app.toShortString(sb);
19797                     sb.append(": over ");
19798                     TimeUtils.formatDuration(uptimeSince, sb);
19799                     sb.append(" used ");
19800                     TimeUtils.formatDuration(cputimeUsed, sb);
19801                     sb.append(" (");
19802                     sb.append((cputimeUsed*100)/uptimeSince);
19803                     sb.append("%)");
19804                     Slog.i(TAG_POWER, sb.toString());
19805                 }
19806                 // If a process has held a wake lock for more
19807                 // than 50% of the time during this period,
19808                 // that sounds bad.  Kill!
19809                 if (doWakeKills && realtimeSince > 0
19810                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
19811                     synchronized (stats) {
19812                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19813                                 realtimeSince, wtimeUsed);
19814                     }
19815                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19816                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19817                 } else if (doCpuKills && uptimeSince > 0
19818                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
19819                     synchronized (stats) {
19820                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19821                                 uptimeSince, cputimeUsed);
19822                     }
19823                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19824                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19825                 } else {
19826                     app.lastWakeTime = wtime;
19827                     app.lastCpuTime = app.curCpuTime;
19828                 }
19829             }
19830         }
19831     }
19832
19833     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19834             long nowElapsed) {
19835         boolean success = true;
19836
19837         if (app.curRawAdj != app.setRawAdj) {
19838             app.setRawAdj = app.curRawAdj;
19839         }
19840
19841         int changes = 0;
19842
19843         if (app.curAdj != app.setAdj) {
19844             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19845             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19846                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19847                     + app.adjType);
19848             app.setAdj = app.curAdj;
19849         }
19850
19851         if (app.setSchedGroup != app.curSchedGroup) {
19852             app.setSchedGroup = app.curSchedGroup;
19853             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19854                     "Setting sched group of " + app.processName
19855                     + " to " + app.curSchedGroup);
19856             if (app.waitingToKill != null && app.curReceiver == null
19857                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19858                 app.kill(app.waitingToKill, true);
19859                 success = false;
19860             } else {
19861                 int processGroup;
19862                 switch (app.curSchedGroup) {
19863                     case ProcessList.SCHED_GROUP_BACKGROUND:
19864                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19865                         break;
19866                     case ProcessList.SCHED_GROUP_TOP_APP:
19867                         processGroup = Process.THREAD_GROUP_TOP_APP;
19868                         break;
19869                     default:
19870                         processGroup = Process.THREAD_GROUP_DEFAULT;
19871                         break;
19872                 }
19873                 if (true) {
19874                     long oldId = Binder.clearCallingIdentity();
19875                     try {
19876                         Process.setProcessGroup(app.pid, processGroup);
19877                     } catch (Exception e) {
19878                         Slog.w(TAG, "Failed setting process group of " + app.pid
19879                                 + " to " + app.curSchedGroup);
19880                         e.printStackTrace();
19881                     } finally {
19882                         Binder.restoreCallingIdentity(oldId);
19883                     }
19884                 } else {
19885                     if (app.thread != null) {
19886                         try {
19887                             app.thread.setSchedulingGroup(processGroup);
19888                         } catch (RemoteException e) {
19889                         }
19890                     }
19891                 }
19892             }
19893         }
19894         if (app.repForegroundActivities != app.foregroundActivities) {
19895             app.repForegroundActivities = app.foregroundActivities;
19896             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19897         }
19898         if (app.repProcState != app.curProcState) {
19899             app.repProcState = app.curProcState;
19900             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19901             if (app.thread != null) {
19902                 try {
19903                     if (false) {
19904                         //RuntimeException h = new RuntimeException("here");
19905                         Slog.i(TAG, "Sending new process state " + app.repProcState
19906                                 + " to " + app /*, h*/);
19907                     }
19908                     app.thread.setProcessState(app.repProcState);
19909                 } catch (RemoteException e) {
19910                 }
19911             }
19912         }
19913         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19914                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19915             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19916                 // Experimental code to more aggressively collect pss while
19917                 // running test...  the problem is that this tends to collect
19918                 // the data right when a process is transitioning between process
19919                 // states, which well tend to give noisy data.
19920                 long start = SystemClock.uptimeMillis();
19921                 long pss = Debug.getPss(app.pid, mTmpLong, null);
19922                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19923                 mPendingPssProcesses.remove(app);
19924                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19925                         + " to " + app.curProcState + ": "
19926                         + (SystemClock.uptimeMillis()-start) + "ms");
19927             }
19928             app.lastStateTime = now;
19929             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19930                     mTestPssMode, isSleeping(), now);
19931             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19932                     + ProcessList.makeProcStateString(app.setProcState) + " to "
19933                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19934                     + (app.nextPssTime-now) + ": " + app);
19935         } else {
19936             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19937                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19938                     mTestPssMode)))) {
19939                 requestPssLocked(app, app.setProcState);
19940                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19941                         mTestPssMode, isSleeping(), now);
19942             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19943                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19944         }
19945         if (app.setProcState != app.curProcState) {
19946             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19947                     "Proc state change of " + app.processName
19948                             + " to " + app.curProcState);
19949             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19950             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19951             if (setImportant && !curImportant) {
19952                 // This app is no longer something we consider important enough to allow to
19953                 // use arbitrary amounts of battery power.  Note
19954                 // its current wake lock time to later know to kill it if
19955                 // it is not behaving well.
19956                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19957                 synchronized (stats) {
19958                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19959                             app.pid, nowElapsed);
19960                 }
19961                 app.lastCpuTime = app.curCpuTime;
19962
19963             }
19964             // Inform UsageStats of important process state change
19965             // Must be called before updating setProcState
19966             maybeUpdateUsageStatsLocked(app, nowElapsed);
19967
19968             app.setProcState = app.curProcState;
19969             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19970                 app.notCachedSinceIdle = false;
19971             }
19972             if (!doingAll) {
19973                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19974             } else {
19975                 app.procStateChanged = true;
19976             }
19977         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19978                 > USAGE_STATS_INTERACTION_INTERVAL) {
19979             // For apps that sit around for a long time in the interactive state, we need
19980             // to report this at least once a day so they don't go idle.
19981             maybeUpdateUsageStatsLocked(app, nowElapsed);
19982         }
19983
19984         if (changes != 0) {
19985             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19986                     "Changes in " + app + ": " + changes);
19987             int i = mPendingProcessChanges.size()-1;
19988             ProcessChangeItem item = null;
19989             while (i >= 0) {
19990                 item = mPendingProcessChanges.get(i);
19991                 if (item.pid == app.pid) {
19992                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19993                             "Re-using existing item: " + item);
19994                     break;
19995                 }
19996                 i--;
19997             }
19998             if (i < 0) {
19999                 // No existing item in pending changes; need a new one.
20000                 final int NA = mAvailProcessChanges.size();
20001                 if (NA > 0) {
20002                     item = mAvailProcessChanges.remove(NA-1);
20003                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20004                             "Retrieving available item: " + item);
20005                 } else {
20006                     item = new ProcessChangeItem();
20007                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20008                             "Allocating new item: " + item);
20009                 }
20010                 item.changes = 0;
20011                 item.pid = app.pid;
20012                 item.uid = app.info.uid;
20013                 if (mPendingProcessChanges.size() == 0) {
20014                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20015                             "*** Enqueueing dispatch processes changed!");
20016                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20017                 }
20018                 mPendingProcessChanges.add(item);
20019             }
20020             item.changes |= changes;
20021             item.processState = app.repProcState;
20022             item.foregroundActivities = app.repForegroundActivities;
20023             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20024                     "Item " + Integer.toHexString(System.identityHashCode(item))
20025                     + " " + app.toShortString() + ": changes=" + item.changes
20026                     + " procState=" + item.processState
20027                     + " foreground=" + item.foregroundActivities
20028                     + " type=" + app.adjType + " source=" + app.adjSource
20029                     + " target=" + app.adjTarget);
20030         }
20031
20032         return success;
20033     }
20034
20035     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20036         final UidRecord.ChangeItem pendingChange;
20037         if (uidRec == null || uidRec.pendingChange == null) {
20038             if (mPendingUidChanges.size() == 0) {
20039                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20040                         "*** Enqueueing dispatch uid changed!");
20041                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20042             }
20043             final int NA = mAvailUidChanges.size();
20044             if (NA > 0) {
20045                 pendingChange = mAvailUidChanges.remove(NA-1);
20046                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20047                         "Retrieving available item: " + pendingChange);
20048             } else {
20049                 pendingChange = new UidRecord.ChangeItem();
20050                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20051                         "Allocating new item: " + pendingChange);
20052             }
20053             if (uidRec != null) {
20054                 uidRec.pendingChange = pendingChange;
20055                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20056                     // If this uid is going away, and we haven't yet reported it is gone,
20057                     // then do so now.
20058                     change = UidRecord.CHANGE_GONE_IDLE;
20059                 }
20060             } else if (uid < 0) {
20061                 throw new IllegalArgumentException("No UidRecord or uid");
20062             }
20063             pendingChange.uidRecord = uidRec;
20064             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20065             mPendingUidChanges.add(pendingChange);
20066         } else {
20067             pendingChange = uidRec.pendingChange;
20068             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20069                 change = UidRecord.CHANGE_GONE_IDLE;
20070             }
20071         }
20072         pendingChange.change = change;
20073         pendingChange.processState = uidRec != null
20074                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20075     }
20076
20077     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20078             String authority) {
20079         if (app == null) return;
20080         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20081             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20082             if (userState == null) return;
20083             final long now = SystemClock.elapsedRealtime();
20084             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20085             if (lastReported == null || lastReported < now - 60 * 1000L) {
20086                 mUsageStatsService.reportContentProviderUsage(
20087                         authority, providerPkgName, app.userId);
20088                 userState.mProviderLastReportedFg.put(authority, now);
20089             }
20090         }
20091     }
20092
20093     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20094         if (DEBUG_USAGE_STATS) {
20095             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20096                     + "] state changes: old = " + app.setProcState + ", new = "
20097                     + app.curProcState);
20098         }
20099         if (mUsageStatsService == null) {
20100             return;
20101         }
20102         boolean isInteraction;
20103         // To avoid some abuse patterns, we are going to be careful about what we consider
20104         // to be an app interaction.  Being the top activity doesn't count while the display
20105         // is sleeping, nor do short foreground services.
20106         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20107             isInteraction = true;
20108             app.fgInteractionTime = 0;
20109         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20110             if (app.fgInteractionTime == 0) {
20111                 app.fgInteractionTime = nowElapsed;
20112                 isInteraction = false;
20113             } else {
20114                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20115             }
20116         } else {
20117             isInteraction = app.curProcState
20118                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20119             app.fgInteractionTime = 0;
20120         }
20121         if (isInteraction && (!app.reportedInteraction
20122                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20123             app.interactionEventTime = nowElapsed;
20124             String[] packages = app.getPackageList();
20125             if (packages != null) {
20126                 for (int i = 0; i < packages.length; i++) {
20127                     mUsageStatsService.reportEvent(packages[i], app.userId,
20128                             UsageEvents.Event.SYSTEM_INTERACTION);
20129                 }
20130             }
20131         }
20132         app.reportedInteraction = isInteraction;
20133         if (!isInteraction) {
20134             app.interactionEventTime = 0;
20135         }
20136     }
20137
20138     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20139         if (proc.thread != null) {
20140             if (proc.baseProcessTracker != null) {
20141                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20142             }
20143         }
20144     }
20145
20146     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20147             ProcessRecord TOP_APP, boolean doingAll, long now) {
20148         if (app.thread == null) {
20149             return false;
20150         }
20151
20152         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20153
20154         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20155     }
20156
20157     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20158             boolean oomAdj) {
20159         if (isForeground != proc.foregroundServices) {
20160             proc.foregroundServices = isForeground;
20161             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20162                     proc.info.uid);
20163             if (isForeground) {
20164                 if (curProcs == null) {
20165                     curProcs = new ArrayList<ProcessRecord>();
20166                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20167                 }
20168                 if (!curProcs.contains(proc)) {
20169                     curProcs.add(proc);
20170                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20171                             proc.info.packageName, proc.info.uid);
20172                 }
20173             } else {
20174                 if (curProcs != null) {
20175                     if (curProcs.remove(proc)) {
20176                         mBatteryStatsService.noteEvent(
20177                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20178                                 proc.info.packageName, proc.info.uid);
20179                         if (curProcs.size() <= 0) {
20180                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20181                         }
20182                     }
20183                 }
20184             }
20185             if (oomAdj) {
20186                 updateOomAdjLocked();
20187             }
20188         }
20189     }
20190
20191     private final ActivityRecord resumedAppLocked() {
20192         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20193         String pkg;
20194         int uid;
20195         if (act != null) {
20196             pkg = act.packageName;
20197             uid = act.info.applicationInfo.uid;
20198         } else {
20199             pkg = null;
20200             uid = -1;
20201         }
20202         // Has the UID or resumed package name changed?
20203         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20204                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20205             if (mCurResumedPackage != null) {
20206                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20207                         mCurResumedPackage, mCurResumedUid);
20208             }
20209             mCurResumedPackage = pkg;
20210             mCurResumedUid = uid;
20211             if (mCurResumedPackage != null) {
20212                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20213                         mCurResumedPackage, mCurResumedUid);
20214             }
20215         }
20216         return act;
20217     }
20218
20219     final boolean updateOomAdjLocked(ProcessRecord app) {
20220         final ActivityRecord TOP_ACT = resumedAppLocked();
20221         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20222         final boolean wasCached = app.cached;
20223
20224         mAdjSeq++;
20225
20226         // This is the desired cached adjusment we want to tell it to use.
20227         // If our app is currently cached, we know it, and that is it.  Otherwise,
20228         // we don't know it yet, and it needs to now be cached we will then
20229         // need to do a complete oom adj.
20230         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20231                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20232         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20233                 SystemClock.uptimeMillis());
20234         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20235             // Changed to/from cached state, so apps after it in the LRU
20236             // list may also be changed.
20237             updateOomAdjLocked();
20238         }
20239         return success;
20240     }
20241
20242     final void updateOomAdjLocked() {
20243         final ActivityRecord TOP_ACT = resumedAppLocked();
20244         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20245         final long now = SystemClock.uptimeMillis();
20246         final long nowElapsed = SystemClock.elapsedRealtime();
20247         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20248         final int N = mLruProcesses.size();
20249
20250         if (false) {
20251             RuntimeException e = new RuntimeException();
20252             e.fillInStackTrace();
20253             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20254         }
20255
20256         // Reset state in all uid records.
20257         for (int i=mActiveUids.size()-1; i>=0; i--) {
20258             final UidRecord uidRec = mActiveUids.valueAt(i);
20259             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20260                     "Starting update of " + uidRec);
20261             uidRec.reset();
20262         }
20263
20264         mStackSupervisor.rankTaskLayersIfNeeded();
20265
20266         mAdjSeq++;
20267         mNewNumServiceProcs = 0;
20268         mNewNumAServiceProcs = 0;
20269
20270         final int emptyProcessLimit;
20271         final int cachedProcessLimit;
20272         if (mProcessLimit <= 0) {
20273             emptyProcessLimit = cachedProcessLimit = 0;
20274         } else if (mProcessLimit == 1) {
20275             emptyProcessLimit = 1;
20276             cachedProcessLimit = 0;
20277         } else {
20278             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20279             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20280         }
20281
20282         // Let's determine how many processes we have running vs.
20283         // how many slots we have for background processes; we may want
20284         // to put multiple processes in a slot of there are enough of
20285         // them.
20286         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20287                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20288         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20289         if (numEmptyProcs > cachedProcessLimit) {
20290             // If there are more empty processes than our limit on cached
20291             // processes, then use the cached process limit for the factor.
20292             // This ensures that the really old empty processes get pushed
20293             // down to the bottom, so if we are running low on memory we will
20294             // have a better chance at keeping around more cached processes
20295             // instead of a gazillion empty processes.
20296             numEmptyProcs = cachedProcessLimit;
20297         }
20298         int emptyFactor = numEmptyProcs/numSlots;
20299         if (emptyFactor < 1) emptyFactor = 1;
20300         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20301         if (cachedFactor < 1) cachedFactor = 1;
20302         int stepCached = 0;
20303         int stepEmpty = 0;
20304         int numCached = 0;
20305         int numEmpty = 0;
20306         int numTrimming = 0;
20307
20308         mNumNonCachedProcs = 0;
20309         mNumCachedHiddenProcs = 0;
20310
20311         // First update the OOM adjustment for each of the
20312         // application processes based on their current state.
20313         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20314         int nextCachedAdj = curCachedAdj+1;
20315         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20316         int nextEmptyAdj = curEmptyAdj+2;
20317         for (int i=N-1; i>=0; i--) {
20318             ProcessRecord app = mLruProcesses.get(i);
20319             if (!app.killedByAm && app.thread != null) {
20320                 app.procStateChanged = false;
20321                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20322
20323                 // If we haven't yet assigned the final cached adj
20324                 // to the process, do that now.
20325                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20326                     switch (app.curProcState) {
20327                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20328                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20329                             // This process is a cached process holding activities...
20330                             // assign it the next cached value for that type, and then
20331                             // step that cached level.
20332                             app.curRawAdj = curCachedAdj;
20333                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20334                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20335                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20336                                     + ")");
20337                             if (curCachedAdj != nextCachedAdj) {
20338                                 stepCached++;
20339                                 if (stepCached >= cachedFactor) {
20340                                     stepCached = 0;
20341                                     curCachedAdj = nextCachedAdj;
20342                                     nextCachedAdj += 2;
20343                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20344                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20345                                     }
20346                                 }
20347                             }
20348                             break;
20349                         default:
20350                             // For everything else, assign next empty cached process
20351                             // level and bump that up.  Note that this means that
20352                             // long-running services that have dropped down to the
20353                             // cached level will be treated as empty (since their process
20354                             // state is still as a service), which is what we want.
20355                             app.curRawAdj = curEmptyAdj;
20356                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20357                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20358                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20359                                     + ")");
20360                             if (curEmptyAdj != nextEmptyAdj) {
20361                                 stepEmpty++;
20362                                 if (stepEmpty >= emptyFactor) {
20363                                     stepEmpty = 0;
20364                                     curEmptyAdj = nextEmptyAdj;
20365                                     nextEmptyAdj += 2;
20366                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20367                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20368                                     }
20369                                 }
20370                             }
20371                             break;
20372                     }
20373                 }
20374
20375                 applyOomAdjLocked(app, true, now, nowElapsed);
20376
20377                 // Count the number of process types.
20378                 switch (app.curProcState) {
20379                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20380                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20381                         mNumCachedHiddenProcs++;
20382                         numCached++;
20383                         if (numCached > cachedProcessLimit) {
20384                             app.kill("cached #" + numCached, true);
20385                         }
20386                         break;
20387                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20388                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20389                                 && app.lastActivityTime < oldTime) {
20390                             app.kill("empty for "
20391                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20392                                     / 1000) + "s", true);
20393                         } else {
20394                             numEmpty++;
20395                             if (numEmpty > emptyProcessLimit) {
20396                                 app.kill("empty #" + numEmpty, true);
20397                             }
20398                         }
20399                         break;
20400                     default:
20401                         mNumNonCachedProcs++;
20402                         break;
20403                 }
20404
20405                 if (app.isolated && app.services.size() <= 0) {
20406                     // If this is an isolated process, and there are no
20407                     // services running in it, then the process is no longer
20408                     // needed.  We agressively kill these because we can by
20409                     // definition not re-use the same process again, and it is
20410                     // good to avoid having whatever code was running in them
20411                     // left sitting around after no longer needed.
20412                     app.kill("isolated not needed", true);
20413                 } else {
20414                     // Keeping this process, update its uid.
20415                     final UidRecord uidRec = app.uidRecord;
20416                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
20417                         uidRec.curProcState = app.curProcState;
20418                     }
20419                 }
20420
20421                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20422                         && !app.killedByAm) {
20423                     numTrimming++;
20424                 }
20425             }
20426         }
20427
20428         mNumServiceProcs = mNewNumServiceProcs;
20429
20430         // Now determine the memory trimming level of background processes.
20431         // Unfortunately we need to start at the back of the list to do this
20432         // properly.  We only do this if the number of background apps we
20433         // are managing to keep around is less than half the maximum we desire;
20434         // if we are keeping a good number around, we'll let them use whatever
20435         // memory they want.
20436         final int numCachedAndEmpty = numCached + numEmpty;
20437         int memFactor;
20438         if (numCached <= ProcessList.TRIM_CACHED_APPS
20439                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20440             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20441                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20442             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20443                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20444             } else {
20445                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20446             }
20447         } else {
20448             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20449         }
20450         // We always allow the memory level to go up (better).  We only allow it to go
20451         // down if we are in a state where that is allowed, *and* the total number of processes
20452         // has gone down since last time.
20453         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20454                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20455                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20456         if (memFactor > mLastMemoryLevel) {
20457             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20458                 memFactor = mLastMemoryLevel;
20459                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20460             }
20461         }
20462         if (memFactor != mLastMemoryLevel) {
20463             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20464         }
20465         mLastMemoryLevel = memFactor;
20466         mLastNumProcesses = mLruProcesses.size();
20467         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20468         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20469         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20470             if (mLowRamStartTime == 0) {
20471                 mLowRamStartTime = now;
20472             }
20473             int step = 0;
20474             int fgTrimLevel;
20475             switch (memFactor) {
20476                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20477                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20478                     break;
20479                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20480                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20481                     break;
20482                 default:
20483                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20484                     break;
20485             }
20486             int factor = numTrimming/3;
20487             int minFactor = 2;
20488             if (mHomeProcess != null) minFactor++;
20489             if (mPreviousProcess != null) minFactor++;
20490             if (factor < minFactor) factor = minFactor;
20491             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20492             for (int i=N-1; i>=0; i--) {
20493                 ProcessRecord app = mLruProcesses.get(i);
20494                 if (allChanged || app.procStateChanged) {
20495                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20496                     app.procStateChanged = false;
20497                 }
20498                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20499                         && !app.killedByAm) {
20500                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
20501                         try {
20502                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20503                                     "Trimming memory of " + app.processName + " to " + curLevel);
20504                             app.thread.scheduleTrimMemory(curLevel);
20505                         } catch (RemoteException e) {
20506                         }
20507                         if (false) {
20508                             // For now we won't do this; our memory trimming seems
20509                             // to be good enough at this point that destroying
20510                             // activities causes more harm than good.
20511                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20512                                     && app != mHomeProcess && app != mPreviousProcess) {
20513                                 // Need to do this on its own message because the stack may not
20514                                 // be in a consistent state at this point.
20515                                 // For these apps we will also finish their activities
20516                                 // to help them free memory.
20517                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20518                             }
20519                         }
20520                     }
20521                     app.trimMemoryLevel = curLevel;
20522                     step++;
20523                     if (step >= factor) {
20524                         step = 0;
20525                         switch (curLevel) {
20526                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20527                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20528                                 break;
20529                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20530                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20531                                 break;
20532                         }
20533                     }
20534                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20535                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20536                             && app.thread != null) {
20537                         try {
20538                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20539                                     "Trimming memory of heavy-weight " + app.processName
20540                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20541                             app.thread.scheduleTrimMemory(
20542                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20543                         } catch (RemoteException e) {
20544                         }
20545                     }
20546                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20547                 } else {
20548                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20549                             || app.systemNoUi) && app.pendingUiClean) {
20550                         // If this application is now in the background and it
20551                         // had done UI, then give it the special trim level to
20552                         // have it free UI resources.
20553                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20554                         if (app.trimMemoryLevel < level && app.thread != null) {
20555                             try {
20556                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20557                                         "Trimming memory of bg-ui " + app.processName
20558                                         + " to " + level);
20559                                 app.thread.scheduleTrimMemory(level);
20560                             } catch (RemoteException e) {
20561                             }
20562                         }
20563                         app.pendingUiClean = false;
20564                     }
20565                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20566                         try {
20567                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20568                                     "Trimming memory of fg " + app.processName
20569                                     + " to " + fgTrimLevel);
20570                             app.thread.scheduleTrimMemory(fgTrimLevel);
20571                         } catch (RemoteException e) {
20572                         }
20573                     }
20574                     app.trimMemoryLevel = fgTrimLevel;
20575                 }
20576             }
20577         } else {
20578             if (mLowRamStartTime != 0) {
20579                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20580                 mLowRamStartTime = 0;
20581             }
20582             for (int i=N-1; i>=0; i--) {
20583                 ProcessRecord app = mLruProcesses.get(i);
20584                 if (allChanged || app.procStateChanged) {
20585                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20586                     app.procStateChanged = false;
20587                 }
20588                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20589                         || app.systemNoUi) && app.pendingUiClean) {
20590                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20591                             && app.thread != null) {
20592                         try {
20593                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20594                                     "Trimming memory of ui hidden " + app.processName
20595                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20596                             app.thread.scheduleTrimMemory(
20597                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20598                         } catch (RemoteException e) {
20599                         }
20600                     }
20601                     app.pendingUiClean = false;
20602                 }
20603                 app.trimMemoryLevel = 0;
20604             }
20605         }
20606
20607         if (mAlwaysFinishActivities) {
20608             // Need to do this on its own message because the stack may not
20609             // be in a consistent state at this point.
20610             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20611         }
20612
20613         if (allChanged) {
20614             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20615         }
20616
20617         // Update from any uid changes.
20618         for (int i=mActiveUids.size()-1; i>=0; i--) {
20619             final UidRecord uidRec = mActiveUids.valueAt(i);
20620             int uidChange = UidRecord.CHANGE_PROCSTATE;
20621             if (uidRec.setProcState != uidRec.curProcState) {
20622                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20623                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20624                         + " to " + uidRec.curProcState);
20625                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20626                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20627                         uidRec.lastBackgroundTime = nowElapsed;
20628                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20629                             // Note: the background settle time is in elapsed realtime, while
20630                             // the handler time base is uptime.  All this means is that we may
20631                             // stop background uids later than we had intended, but that only
20632                             // happens because the device was sleeping so we are okay anyway.
20633                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20634                         }
20635                     }
20636                 } else {
20637                     if (uidRec.idle) {
20638                         uidChange = UidRecord.CHANGE_ACTIVE;
20639                         uidRec.idle = false;
20640                     }
20641                     uidRec.lastBackgroundTime = 0;
20642                 }
20643                 uidRec.setProcState = uidRec.curProcState;
20644                 enqueueUidChangeLocked(uidRec, -1, uidChange);
20645                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20646             }
20647         }
20648
20649         if (mProcessStats.shouldWriteNowLocked(now)) {
20650             mHandler.post(new Runnable() {
20651                 @Override public void run() {
20652                     synchronized (ActivityManagerService.this) {
20653                         mProcessStats.writeStateAsyncLocked();
20654                     }
20655                 }
20656             });
20657         }
20658
20659         if (DEBUG_OOM_ADJ) {
20660             final long duration = SystemClock.uptimeMillis() - now;
20661             if (false) {
20662                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20663                         new RuntimeException("here").fillInStackTrace());
20664             } else {
20665                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20666             }
20667         }
20668     }
20669
20670     final void idleUids() {
20671         synchronized (this) {
20672             final long nowElapsed = SystemClock.elapsedRealtime();
20673             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20674             long nextTime = 0;
20675             for (int i=mActiveUids.size()-1; i>=0; i--) {
20676                 final UidRecord uidRec = mActiveUids.valueAt(i);
20677                 final long bgTime = uidRec.lastBackgroundTime;
20678                 if (bgTime > 0 && !uidRec.idle) {
20679                     if (bgTime <= maxBgTime) {
20680                         uidRec.idle = true;
20681                         doStopUidLocked(uidRec.uid, uidRec);
20682                     } else {
20683                         if (nextTime == 0 || nextTime > bgTime) {
20684                             nextTime = bgTime;
20685                         }
20686                     }
20687                 }
20688             }
20689             if (nextTime > 0) {
20690                 mHandler.removeMessages(IDLE_UIDS_MSG);
20691                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20692                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20693             }
20694         }
20695     }
20696
20697     final void runInBackgroundDisabled(int uid) {
20698         synchronized (this) {
20699             UidRecord uidRec = mActiveUids.get(uid);
20700             if (uidRec != null) {
20701                 // This uid is actually running...  should it be considered background now?
20702                 if (uidRec.idle) {
20703                     doStopUidLocked(uidRec.uid, uidRec);
20704                 }
20705             } else {
20706                 // This uid isn't actually running...  still send a report about it being "stopped".
20707                 doStopUidLocked(uid, null);
20708             }
20709         }
20710     }
20711
20712     final void doStopUidLocked(int uid, final UidRecord uidRec) {
20713         mServices.stopInBackgroundLocked(uid);
20714         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20715     }
20716
20717     final void trimApplications() {
20718         synchronized (this) {
20719             int i;
20720
20721             // First remove any unused application processes whose package
20722             // has been removed.
20723             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20724                 final ProcessRecord app = mRemovedProcesses.get(i);
20725                 if (app.activities.size() == 0
20726                         && app.curReceiver == null && app.services.size() == 0) {
20727                     Slog.i(
20728                         TAG, "Exiting empty application process "
20729                         + app.toShortString() + " ("
20730                         + (app.thread != null ? app.thread.asBinder() : null)
20731                         + ")\n");
20732                     if (app.pid > 0 && app.pid != MY_PID) {
20733                         app.kill("empty", false);
20734                     } else {
20735                         try {
20736                             app.thread.scheduleExit();
20737                         } catch (Exception e) {
20738                             // Ignore exceptions.
20739                         }
20740                     }
20741                     cleanUpApplicationRecordLocked(app, false, true, -1);
20742                     mRemovedProcesses.remove(i);
20743
20744                     if (app.persistent) {
20745                         addAppLocked(app.info, false, null /* ABI override */);
20746                     }
20747                 }
20748             }
20749
20750             // Now update the oom adj for all processes.
20751             updateOomAdjLocked();
20752         }
20753     }
20754
20755     /** This method sends the specified signal to each of the persistent apps */
20756     public void signalPersistentProcesses(int sig) throws RemoteException {
20757         if (sig != Process.SIGNAL_USR1) {
20758             throw new SecurityException("Only SIGNAL_USR1 is allowed");
20759         }
20760
20761         synchronized (this) {
20762             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20763                     != PackageManager.PERMISSION_GRANTED) {
20764                 throw new SecurityException("Requires permission "
20765                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20766             }
20767
20768             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20769                 ProcessRecord r = mLruProcesses.get(i);
20770                 if (r.thread != null && r.persistent) {
20771                     Process.sendSignal(r.pid, sig);
20772                 }
20773             }
20774         }
20775     }
20776
20777     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20778         if (proc == null || proc == mProfileProc) {
20779             proc = mProfileProc;
20780             profileType = mProfileType;
20781             clearProfilerLocked();
20782         }
20783         if (proc == null) {
20784             return;
20785         }
20786         try {
20787             proc.thread.profilerControl(false, null, profileType);
20788         } catch (RemoteException e) {
20789             throw new IllegalStateException("Process disappeared");
20790         }
20791     }
20792
20793     private void clearProfilerLocked() {
20794         if (mProfileFd != null) {
20795             try {
20796                 mProfileFd.close();
20797             } catch (IOException e) {
20798             }
20799         }
20800         mProfileApp = null;
20801         mProfileProc = null;
20802         mProfileFile = null;
20803         mProfileType = 0;
20804         mAutoStopProfiler = false;
20805         mSamplingInterval = 0;
20806     }
20807
20808     public boolean profileControl(String process, int userId, boolean start,
20809             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20810
20811         try {
20812             synchronized (this) {
20813                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20814                 // its own permission.
20815                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20816                         != PackageManager.PERMISSION_GRANTED) {
20817                     throw new SecurityException("Requires permission "
20818                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20819                 }
20820
20821                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20822                     throw new IllegalArgumentException("null profile info or fd");
20823                 }
20824
20825                 ProcessRecord proc = null;
20826                 if (process != null) {
20827                     proc = findProcessLocked(process, userId, "profileControl");
20828                 }
20829
20830                 if (start && (proc == null || proc.thread == null)) {
20831                     throw new IllegalArgumentException("Unknown process: " + process);
20832                 }
20833
20834                 if (start) {
20835                     stopProfilerLocked(null, 0);
20836                     setProfileApp(proc.info, proc.processName, profilerInfo);
20837                     mProfileProc = proc;
20838                     mProfileType = profileType;
20839                     ParcelFileDescriptor fd = profilerInfo.profileFd;
20840                     try {
20841                         fd = fd.dup();
20842                     } catch (IOException e) {
20843                         fd = null;
20844                     }
20845                     profilerInfo.profileFd = fd;
20846                     proc.thread.profilerControl(start, profilerInfo, profileType);
20847                     fd = null;
20848                     mProfileFd = null;
20849                 } else {
20850                     stopProfilerLocked(proc, profileType);
20851                     if (profilerInfo != null && profilerInfo.profileFd != null) {
20852                         try {
20853                             profilerInfo.profileFd.close();
20854                         } catch (IOException e) {
20855                         }
20856                     }
20857                 }
20858
20859                 return true;
20860             }
20861         } catch (RemoteException e) {
20862             throw new IllegalStateException("Process disappeared");
20863         } finally {
20864             if (profilerInfo != null && profilerInfo.profileFd != null) {
20865                 try {
20866                     profilerInfo.profileFd.close();
20867                 } catch (IOException e) {
20868                 }
20869             }
20870         }
20871     }
20872
20873     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20874         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20875                 userId, true, ALLOW_FULL_ONLY, callName, null);
20876         ProcessRecord proc = null;
20877         try {
20878             int pid = Integer.parseInt(process);
20879             synchronized (mPidsSelfLocked) {
20880                 proc = mPidsSelfLocked.get(pid);
20881             }
20882         } catch (NumberFormatException e) {
20883         }
20884
20885         if (proc == null) {
20886             ArrayMap<String, SparseArray<ProcessRecord>> all
20887                     = mProcessNames.getMap();
20888             SparseArray<ProcessRecord> procs = all.get(process);
20889             if (procs != null && procs.size() > 0) {
20890                 proc = procs.valueAt(0);
20891                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20892                     for (int i=1; i<procs.size(); i++) {
20893                         ProcessRecord thisProc = procs.valueAt(i);
20894                         if (thisProc.userId == userId) {
20895                             proc = thisProc;
20896                             break;
20897                         }
20898                     }
20899                 }
20900             }
20901         }
20902
20903         return proc;
20904     }
20905
20906     public boolean dumpHeap(String process, int userId, boolean managed,
20907             String path, ParcelFileDescriptor fd) throws RemoteException {
20908
20909         try {
20910             synchronized (this) {
20911                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20912                 // its own permission (same as profileControl).
20913                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20914                         != PackageManager.PERMISSION_GRANTED) {
20915                     throw new SecurityException("Requires permission "
20916                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20917                 }
20918
20919                 if (fd == null) {
20920                     throw new IllegalArgumentException("null fd");
20921                 }
20922
20923                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20924                 if (proc == null || proc.thread == null) {
20925                     throw new IllegalArgumentException("Unknown process: " + process);
20926                 }
20927
20928                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20929                 if (!isDebuggable) {
20930                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20931                         throw new SecurityException("Process not debuggable: " + proc);
20932                     }
20933                 }
20934
20935                 proc.thread.dumpHeap(managed, path, fd);
20936                 fd = null;
20937                 return true;
20938             }
20939         } catch (RemoteException e) {
20940             throw new IllegalStateException("Process disappeared");
20941         } finally {
20942             if (fd != null) {
20943                 try {
20944                     fd.close();
20945                 } catch (IOException e) {
20946                 }
20947             }
20948         }
20949     }
20950
20951     @Override
20952     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20953             String reportPackage) {
20954         if (processName != null) {
20955             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20956                     "setDumpHeapDebugLimit()");
20957         } else {
20958             synchronized (mPidsSelfLocked) {
20959                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20960                 if (proc == null) {
20961                     throw new SecurityException("No process found for calling pid "
20962                             + Binder.getCallingPid());
20963                 }
20964                 if (!Build.IS_DEBUGGABLE
20965                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20966                     throw new SecurityException("Not running a debuggable build");
20967                 }
20968                 processName = proc.processName;
20969                 uid = proc.uid;
20970                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20971                     throw new SecurityException("Package " + reportPackage + " is not running in "
20972                             + proc);
20973                 }
20974             }
20975         }
20976         synchronized (this) {
20977             if (maxMemSize > 0) {
20978                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20979             } else {
20980                 if (uid != 0) {
20981                     mMemWatchProcesses.remove(processName, uid);
20982                 } else {
20983                     mMemWatchProcesses.getMap().remove(processName);
20984                 }
20985             }
20986         }
20987     }
20988
20989     @Override
20990     public void dumpHeapFinished(String path) {
20991         synchronized (this) {
20992             if (Binder.getCallingPid() != mMemWatchDumpPid) {
20993                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20994                         + " does not match last pid " + mMemWatchDumpPid);
20995                 return;
20996             }
20997             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20998                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20999                         + " does not match last path " + mMemWatchDumpFile);
21000                 return;
21001             }
21002             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21003             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21004         }
21005     }
21006
21007     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21008     public void monitor() {
21009         synchronized (this) { }
21010     }
21011
21012     void onCoreSettingsChange(Bundle settings) {
21013         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21014             ProcessRecord processRecord = mLruProcesses.get(i);
21015             try {
21016                 if (processRecord.thread != null) {
21017                     processRecord.thread.setCoreSettings(settings);
21018                 }
21019             } catch (RemoteException re) {
21020                 /* ignore */
21021             }
21022         }
21023     }
21024
21025     // Multi-user methods
21026
21027     /**
21028      * Start user, if its not already running, but don't bring it to foreground.
21029      */
21030     @Override
21031     public boolean startUserInBackground(final int userId) {
21032         return mUserController.startUser(userId, /* foreground */ false);
21033     }
21034
21035     @Override
21036     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21037         return mUserController.unlockUser(userId, token, secret, listener);
21038     }
21039
21040     @Override
21041     public boolean switchUser(final int targetUserId) {
21042         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21043         UserInfo currentUserInfo;
21044         UserInfo targetUserInfo;
21045         synchronized (this) {
21046             int currentUserId = mUserController.getCurrentUserIdLocked();
21047             currentUserInfo = mUserController.getUserInfo(currentUserId);
21048             targetUserInfo = mUserController.getUserInfo(targetUserId);
21049             if (targetUserInfo == null) {
21050                 Slog.w(TAG, "No user info for user #" + targetUserId);
21051                 return false;
21052             }
21053             if (!targetUserInfo.supportsSwitchTo()) {
21054                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21055                 return false;
21056             }
21057             if (targetUserInfo.isManagedProfile()) {
21058                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21059                 return false;
21060             }
21061             mUserController.setTargetUserIdLocked(targetUserId);
21062         }
21063         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21064         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21065         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21066         return true;
21067     }
21068
21069     void scheduleStartProfilesLocked() {
21070         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21071             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21072                     DateUtils.SECOND_IN_MILLIS);
21073         }
21074     }
21075
21076     @Override
21077     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21078         return mUserController.stopUser(userId, force, callback);
21079     }
21080
21081     @Override
21082     public UserInfo getCurrentUser() {
21083         return mUserController.getCurrentUser();
21084     }
21085
21086     @Override
21087     public boolean isUserRunning(int userId, int flags) {
21088         if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21089                 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21090             String msg = "Permission Denial: isUserRunning() from pid="
21091                     + Binder.getCallingPid()
21092                     + ", uid=" + Binder.getCallingUid()
21093                     + " requires " + INTERACT_ACROSS_USERS;
21094             Slog.w(TAG, msg);
21095             throw new SecurityException(msg);
21096         }
21097         synchronized (this) {
21098             return mUserController.isUserRunningLocked(userId, flags);
21099         }
21100     }
21101
21102     @Override
21103     public int[] getRunningUserIds() {
21104         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21105                 != PackageManager.PERMISSION_GRANTED) {
21106             String msg = "Permission Denial: isUserRunning() from pid="
21107                     + Binder.getCallingPid()
21108                     + ", uid=" + Binder.getCallingUid()
21109                     + " requires " + INTERACT_ACROSS_USERS;
21110             Slog.w(TAG, msg);
21111             throw new SecurityException(msg);
21112         }
21113         synchronized (this) {
21114             return mUserController.getStartedUserArrayLocked();
21115         }
21116     }
21117
21118     @Override
21119     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21120         mUserController.registerUserSwitchObserver(observer);
21121     }
21122
21123     @Override
21124     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21125         mUserController.unregisterUserSwitchObserver(observer);
21126     }
21127
21128     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21129         if (info == null) return null;
21130         ApplicationInfo newInfo = new ApplicationInfo(info);
21131         newInfo.initForUser(userId);
21132         return newInfo;
21133     }
21134
21135     public boolean isUserStopped(int userId) {
21136         synchronized (this) {
21137             return mUserController.getStartedUserStateLocked(userId) == null;
21138         }
21139     }
21140
21141     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21142         if (aInfo == null
21143                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21144             return aInfo;
21145         }
21146
21147         ActivityInfo info = new ActivityInfo(aInfo);
21148         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21149         return info;
21150     }
21151
21152     private boolean processSanityChecksLocked(ProcessRecord process) {
21153         if (process == null || process.thread == null) {
21154             return false;
21155         }
21156
21157         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21158         if (!isDebuggable) {
21159             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21160                 return false;
21161             }
21162         }
21163
21164         return true;
21165     }
21166
21167     public boolean startBinderTracking() throws RemoteException {
21168         synchronized (this) {
21169             mBinderTransactionTrackingEnabled = true;
21170             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21171             // permission (same as profileControl).
21172             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21173                     != PackageManager.PERMISSION_GRANTED) {
21174                 throw new SecurityException("Requires permission "
21175                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21176             }
21177
21178             for (int i = 0; i < mLruProcesses.size(); i++) {
21179                 ProcessRecord process = mLruProcesses.get(i);
21180                 if (!processSanityChecksLocked(process)) {
21181                     continue;
21182                 }
21183                 try {
21184                     process.thread.startBinderTracking();
21185                 } catch (RemoteException e) {
21186                     Log.v(TAG, "Process disappared");
21187                 }
21188             }
21189             return true;
21190         }
21191     }
21192
21193     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21194         try {
21195             synchronized (this) {
21196                 mBinderTransactionTrackingEnabled = false;
21197                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21198                 // permission (same as profileControl).
21199                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21200                         != PackageManager.PERMISSION_GRANTED) {
21201                     throw new SecurityException("Requires permission "
21202                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21203                 }
21204
21205                 if (fd == null) {
21206                     throw new IllegalArgumentException("null fd");
21207                 }
21208
21209                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21210                 pw.println("Binder transaction traces for all processes.\n");
21211                 for (ProcessRecord process : mLruProcesses) {
21212                     if (!processSanityChecksLocked(process)) {
21213                         continue;
21214                     }
21215
21216                     pw.println("Traces for process: " + process.processName);
21217                     pw.flush();
21218                     try {
21219                         TransferPipe tp = new TransferPipe();
21220                         try {
21221                             process.thread.stopBinderTrackingAndDump(
21222                                     tp.getWriteFd().getFileDescriptor());
21223                             tp.go(fd.getFileDescriptor());
21224                         } finally {
21225                             tp.kill();
21226                         }
21227                     } catch (IOException e) {
21228                         pw.println("Failure while dumping IPC traces from " + process +
21229                                 ".  Exception: " + e);
21230                         pw.flush();
21231                     } catch (RemoteException e) {
21232                         pw.println("Got a RemoteException while dumping IPC traces from " +
21233                                 process + ".  Exception: " + e);
21234                         pw.flush();
21235                     }
21236                 }
21237                 fd = null;
21238                 return true;
21239             }
21240         } finally {
21241             if (fd != null) {
21242                 try {
21243                     fd.close();
21244                 } catch (IOException e) {
21245                 }
21246             }
21247         }
21248     }
21249
21250     private final class LocalService extends ActivityManagerInternal {
21251         @Override
21252         public void onWakefulnessChanged(int wakefulness) {
21253             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21254         }
21255
21256         @Override
21257         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21258                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21259             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21260                     processName, abiOverride, uid, crashHandler);
21261         }
21262
21263         @Override
21264         public SleepToken acquireSleepToken(String tag) {
21265             Preconditions.checkNotNull(tag);
21266
21267             synchronized (ActivityManagerService.this) {
21268                 SleepTokenImpl token = new SleepTokenImpl(tag);
21269                 mSleepTokens.add(token);
21270                 updateSleepIfNeededLocked();
21271                 applyVrModeIfNeededLocked(mFocusedActivity, false);
21272                 return token;
21273             }
21274         }
21275
21276         @Override
21277         public ComponentName getHomeActivityForUser(int userId) {
21278             synchronized (ActivityManagerService.this) {
21279                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21280                 return homeActivity == null ? null : homeActivity.realActivity;
21281             }
21282         }
21283
21284         @Override
21285         public void onUserRemoved(int userId) {
21286             synchronized (ActivityManagerService.this) {
21287                 ActivityManagerService.this.onUserStoppedLocked(userId);
21288             }
21289         }
21290
21291         @Override
21292         public void onLocalVoiceInteractionStarted(IBinder activity,
21293                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21294             synchronized (ActivityManagerService.this) {
21295                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21296                         voiceSession, voiceInteractor);
21297             }
21298         }
21299
21300         @Override
21301         public void notifyStartingWindowDrawn() {
21302             synchronized (ActivityManagerService.this) {
21303                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21304             }
21305         }
21306
21307         @Override
21308         public void notifyAppTransitionStarting(int reason) {
21309             synchronized (ActivityManagerService.this) {
21310                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21311             }
21312         }
21313
21314         @Override
21315         public void notifyAppTransitionFinished() {
21316             synchronized (ActivityManagerService.this) {
21317                 mStackSupervisor.notifyAppTransitionDone();
21318             }
21319         }
21320
21321         @Override
21322         public void notifyAppTransitionCancelled() {
21323             synchronized (ActivityManagerService.this) {
21324                 mStackSupervisor.notifyAppTransitionDone();
21325             }
21326         }
21327
21328         @Override
21329         public List<IBinder> getTopVisibleActivities() {
21330             synchronized (ActivityManagerService.this) {
21331                 return mStackSupervisor.getTopVisibleActivities();
21332             }
21333         }
21334
21335         @Override
21336         public void notifyDockedStackMinimizedChanged(boolean minimized) {
21337             synchronized (ActivityManagerService.this) {
21338                 mStackSupervisor.setDockedStackMinimized(minimized);
21339             }
21340         }
21341
21342         @Override
21343         public void killForegroundAppsForUser(int userHandle) {
21344             synchronized (ActivityManagerService.this) {
21345                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21346                 final int NP = mProcessNames.getMap().size();
21347                 for (int ip = 0; ip < NP; ip++) {
21348                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21349                     final int NA = apps.size();
21350                     for (int ia = 0; ia < NA; ia++) {
21351                         final ProcessRecord app = apps.valueAt(ia);
21352                         if (app.persistent) {
21353                             // We don't kill persistent processes.
21354                             continue;
21355                         }
21356                         if (app.removed) {
21357                             procs.add(app);
21358                         } else if (app.userId == userHandle && app.foregroundActivities) {
21359                             app.removed = true;
21360                             procs.add(app);
21361                         }
21362                     }
21363                 }
21364
21365                 final int N = procs.size();
21366                 for (int i = 0; i < N; i++) {
21367                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
21368                 }
21369             }
21370         }
21371
21372         @Override
21373         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21374             if (!(target instanceof PendingIntentRecord)) {
21375                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21376                 return;
21377             }
21378             ((PendingIntentRecord) target).setWhitelistDuration(duration);
21379         }
21380     }
21381
21382     private final class SleepTokenImpl extends SleepToken {
21383         private final String mTag;
21384         private final long mAcquireTime;
21385
21386         public SleepTokenImpl(String tag) {
21387             mTag = tag;
21388             mAcquireTime = SystemClock.uptimeMillis();
21389         }
21390
21391         @Override
21392         public void release() {
21393             synchronized (ActivityManagerService.this) {
21394                 if (mSleepTokens.remove(this)) {
21395                     updateSleepIfNeededLocked();
21396                 }
21397             }
21398         }
21399
21400         @Override
21401         public String toString() {
21402             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21403         }
21404     }
21405
21406     /**
21407      * An implementation of IAppTask, that allows an app to manage its own tasks via
21408      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21409      * only the process that calls getAppTasks() can call the AppTask methods.
21410      */
21411     class AppTaskImpl extends IAppTask.Stub {
21412         private int mTaskId;
21413         private int mCallingUid;
21414
21415         public AppTaskImpl(int taskId, int callingUid) {
21416             mTaskId = taskId;
21417             mCallingUid = callingUid;
21418         }
21419
21420         private void checkCaller() {
21421             if (mCallingUid != Binder.getCallingUid()) {
21422                 throw new SecurityException("Caller " + mCallingUid
21423                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21424             }
21425         }
21426
21427         @Override
21428         public void finishAndRemoveTask() {
21429             checkCaller();
21430
21431             synchronized (ActivityManagerService.this) {
21432                 long origId = Binder.clearCallingIdentity();
21433                 try {
21434                     // We remove the task from recents to preserve backwards
21435                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21436                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21437                     }
21438                 } finally {
21439                     Binder.restoreCallingIdentity(origId);
21440                 }
21441             }
21442         }
21443
21444         @Override
21445         public ActivityManager.RecentTaskInfo getTaskInfo() {
21446             checkCaller();
21447
21448             synchronized (ActivityManagerService.this) {
21449                 long origId = Binder.clearCallingIdentity();
21450                 try {
21451                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21452                     if (tr == null) {
21453                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21454                     }
21455                     return createRecentTaskInfoFromTaskRecord(tr);
21456                 } finally {
21457                     Binder.restoreCallingIdentity(origId);
21458                 }
21459             }
21460         }
21461
21462         @Override
21463         public void moveToFront() {
21464             checkCaller();
21465             // Will bring task to front if it already has a root activity.
21466             final long origId = Binder.clearCallingIdentity();
21467             try {
21468                 synchronized (this) {
21469                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21470                 }
21471             } finally {
21472                 Binder.restoreCallingIdentity(origId);
21473             }
21474         }
21475
21476         @Override
21477         public int startActivity(IBinder whoThread, String callingPackage,
21478                 Intent intent, String resolvedType, Bundle bOptions) {
21479             checkCaller();
21480
21481             int callingUser = UserHandle.getCallingUserId();
21482             TaskRecord tr;
21483             IApplicationThread appThread;
21484             synchronized (ActivityManagerService.this) {
21485                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21486                 if (tr == null) {
21487                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21488                 }
21489                 appThread = ApplicationThreadNative.asInterface(whoThread);
21490                 if (appThread == null) {
21491                     throw new IllegalArgumentException("Bad app thread " + appThread);
21492                 }
21493             }
21494             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21495                     resolvedType, null, null, null, null, 0, 0, null, null,
21496                     null, bOptions, false, callingUser, null, tr);
21497         }
21498
21499         @Override
21500         public void setExcludeFromRecents(boolean exclude) {
21501             checkCaller();
21502
21503             synchronized (ActivityManagerService.this) {
21504                 long origId = Binder.clearCallingIdentity();
21505                 try {
21506                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21507                     if (tr == null) {
21508                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21509                     }
21510                     Intent intent = tr.getBaseIntent();
21511                     if (exclude) {
21512                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21513                     } else {
21514                         intent.setFlags(intent.getFlags()
21515                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21516                     }
21517                 } finally {
21518                     Binder.restoreCallingIdentity(origId);
21519                 }
21520             }
21521         }
21522     }
21523
21524     /**
21525      * Kill processes for the user with id userId and that depend on the package named packageName
21526      */
21527     @Override
21528     public void killPackageDependents(String packageName, int userId) {
21529         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21530         if (packageName == null) {
21531             throw new NullPointerException(
21532                     "Cannot kill the dependents of a package without its name.");
21533         }
21534
21535         long callingId = Binder.clearCallingIdentity();
21536         IPackageManager pm = AppGlobals.getPackageManager();
21537         int pkgUid = -1;
21538         try {
21539             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21540         } catch (RemoteException e) {
21541         }
21542         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21543             throw new IllegalArgumentException(
21544                     "Cannot kill dependents of non-existing package " + packageName);
21545         }
21546         try {
21547             synchronized(this) {
21548                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21549                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21550                         "dep: " + packageName);
21551             }
21552         } finally {
21553             Binder.restoreCallingIdentity(callingId);
21554         }
21555     }
21556 }