OSDN Git Service

[RESTRICT AUTOMERGE] Pass correct realCallingUid to startActivity() from startActivit...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
60
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
64
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
223
224 import java.io.File;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
249
250 import dalvik.system.VMRuntime;
251
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
254
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374 public final class ActivityManagerService extends ActivityManagerNative
375         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386     private static final String TAG_LRU = TAG + POSTFIX_LRU;
387     private static final String TAG_MU = TAG + POSTFIX_MU;
388     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389     private static final String TAG_POWER = TAG + POSTFIX_POWER;
390     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393     private static final String TAG_PSS = TAG + POSTFIX_PSS;
394     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396     private static final String TAG_STACK = TAG + POSTFIX_STACK;
397     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404     // here so that while the job scheduler can depend on AMS, the other way around
405     // need not be the case.
406     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408     /** Control over CPU and battery monitoring */
409     // write battery stats every 30 minutes.
410     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411     static final boolean MONITOR_CPU_USAGE = true;
412     // don't sample cpu less than every 5 seconds.
413     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414     // wait possibly forever for next cpu sample.
415     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416     static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418     // The flags that are set for all calls we make to the package manager.
419     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425     // Amount of time after a call to stopAppSwitches() during which we will
426     // prevent further untrusted switches from happening.
427     static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429     // How long we wait for a launched process to attach to the activity manager
430     // before we decide it's never going to come up for real.
431     static final int PROC_START_TIMEOUT = 10*1000;
432     // How long we wait for an attached process to publish its content providers
433     // before we decide it must be hung.
434     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436     // How long we will retain processes hosting content providers in the "last activity"
437     // state before allowing them to drop down to the regular cached LRU list.  This is
438     // to avoid thrashing of provider processes under low memory situations.
439     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441     // How long we wait for a launched process to attach to the activity manager
442     // before we decide it's never going to come up for real, when the process was
443     // started with a wrapper for instrumentation (such as Valgrind) because it
444     // could take much longer than usual.
445     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447     // How long to wait after going idle before forcing apps to GC.
448     static final int GC_TIMEOUT = 5*1000;
449
450     // The minimum amount of time between successive GC requests for a process.
451     static final int GC_MIN_INTERVAL = 60*1000;
452
453     // The minimum amount of time between successive PSS requests for a process.
454     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456     // The minimum amount of time between successive PSS requests for a process
457     // when the request is due to the memory state being lowered.
458     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460     // The rate at which we check for apps using excessive power -- 15 mins.
461     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463     // The minimum sample duration we will allow before deciding we have
464     // enough data on wake locks to start killing things.
465     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467     // The minimum sample duration we will allow before deciding we have
468     // enough data on CPU usage to start killing things.
469     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471     // How long we allow a receiver to run before giving up on it.
472     static final int BROADCAST_FG_TIMEOUT = 10*1000;
473     static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475     // How long we wait until we timeout on key dispatching.
476     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478     // How long we wait until we timeout on key dispatching during instrumentation.
479     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481     // This is the amount of time an app needs to be running a foreground service before
482     // we will consider it to be doing interaction for usage stats.
483     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485     // Maximum amount of time we will allow to elapse before re-reporting usage stats
486     // interaction with foreground processes.
487     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489     // This is the amount of time we allow an app to settle after it goes into the background,
490     // before we start restricting what it can do.
491     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493     // How long to wait in getAssistContextExtras for the activity and foreground services
494     // to respond with the result.
495     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497     // How long top wait when going through the modern assist (which doesn't need to block
498     // on getting this result before starting to launch its UI).
499     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501     // Maximum number of persisted Uri grants a package is allowed
502     static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504     static final int MY_PID = Process.myPid();
505
506     static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508     // How many bytes to write into the dropbox log before truncating
509     static final int DROPBOX_MAX_SIZE = 192 * 1024;
510     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511     // as one line, but close enough for now.
512     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514     // Access modes for handleIncomingUser.
515     static final int ALLOW_NON_FULL = 0;
516     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517     static final int ALLOW_FULL_ONLY = 2;
518
519     // Delay in notifying task stack change listeners (in millis)
520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522     // Necessary ApplicationInfo flags to mark an app as persistent
523     private static final int PERSISTENT_MASK =
524             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526     // Intent sent when remote bugreport collection has been completed
527     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530     // Delay to disable app launch boost
531     static final int APP_BOOST_MESSAGE_DELAY = 3000;
532     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533     static final int APP_BOOST_TIMEOUT = 2500;
534
535     // Used to indicate that a task is removed it should also be removed from recents.
536     private static final boolean REMOVE_FROM_RECENTS = true;
537     // Used to indicate that an app transition should be animated.
538     static final boolean ANIMATE = true;
539
540     // Determines whether to take full screen screenshots
541     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544     private static native int nativeMigrateToBoost();
545     private static native int nativeMigrateFromBoost();
546     private boolean mIsBoosted = false;
547     private long mBoostStartTime = 0;
548
549     /** All system services */
550     SystemServiceManager mSystemServiceManager;
551
552     private Installer mInstaller;
553
554     /** Run all ActivityStacks through this */
555     final ActivityStackSupervisor mStackSupervisor;
556
557     final ActivityStarter mActivityStarter;
558
559     /** Task stack change listeners. */
560     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561             new RemoteCallbackList<ITaskStackListener>();
562
563     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565     public IntentFirewall mIntentFirewall;
566
567     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568     // default actuion automatically.  Important for devices without direct input
569     // devices.
570     private boolean mShowDialogs = true;
571     private boolean mInVrMode = false;
572
573     // Whether we should use SCHED_FIFO for UI and RenderThreads.
574     private boolean mUseFifoUiScheduling = false;
575
576     BroadcastQueue mFgBroadcastQueue;
577     BroadcastQueue mBgBroadcastQueue;
578     // Convenient for easy iteration over the queues. Foreground is first
579     // so that dispatch of foreground broadcasts gets precedence.
580     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582     BroadcastStats mLastBroadcastStats;
583     BroadcastStats mCurBroadcastStats;
584
585     BroadcastQueue broadcastQueueForIntent(Intent intent) {
586         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                 "Broadcast intent " + intent + " on "
589                 + (isFg ? "foreground" : "background") + " queue");
590         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591     }
592
593     /**
594      * Activity we have told the window manager to have key focus.
595      */
596     ActivityRecord mFocusedActivity = null;
597
598     /**
599      * User id of the last activity mFocusedActivity was set to.
600      */
601     private int mLastFocusedUserId;
602
603     /**
604      * If non-null, we are tracking the time the user spends in the currently focused app.
605      */
606     private AppTimeTracker mCurAppTimeTracker;
607
608     /**
609      * List of intents that were used to start the most recent tasks.
610      */
611     final RecentTasks mRecentTasks;
612
613     /**
614      * For addAppTask: cached of the last activity component that was added.
615      */
616     ComponentName mLastAddedTaskComponent;
617
618     /**
619      * For addAppTask: cached of the last activity uid that was added.
620      */
621     int mLastAddedTaskUid;
622
623     /**
624      * For addAppTask: cached of the last ActivityInfo that was added.
625      */
626     ActivityInfo mLastAddedTaskActivity;
627
628     /**
629      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630      */
631     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633     /**
634      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635      */
636     String mDeviceOwnerName;
637
638     final UserController mUserController;
639
640     final AppErrors mAppErrors;
641
642     boolean mDoingSetFocusedActivity;
643
644     public boolean canShowErrorDialogs() {
645         return mShowDialogs && !mSleeping && !mShuttingDown
646                 && mLockScreenShown != LOCK_SCREEN_SHOWN;
647     }
648
649     private static final class PriorityState {
650         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651         // the current thread is currently in. When it drops down to zero, we will no longer boost
652         // the thread's priority.
653         private int regionCounter = 0;
654
655         // The thread's previous priority before boosting.
656         private int prevPriority = Integer.MIN_VALUE;
657     }
658
659     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660         @Override protected PriorityState initialValue() {
661             return new PriorityState();
662         }
663     };
664
665     static void boostPriorityForLockedSection() {
666         int tid = Process.myTid();
667         int prevPriority = Process.getThreadPriority(tid);
668         PriorityState state = sThreadPriorityState.get();
669         if (state.regionCounter == 0 && prevPriority > -2) {
670             state.prevPriority = prevPriority;
671             Process.setThreadPriority(tid, -2);
672         }
673         state.regionCounter++;
674     }
675
676     static void resetPriorityAfterLockedSection() {
677         PriorityState state = sThreadPriorityState.get();
678         state.regionCounter--;
679         if (state.regionCounter == 0 && state.prevPriority > -2) {
680             Process.setThreadPriority(Process.myTid(), state.prevPriority);
681         }
682     }
683
684     public class PendingAssistExtras extends Binder implements Runnable {
685         public final ActivityRecord activity;
686         public final Bundle extras;
687         public final Intent intent;
688         public final String hint;
689         public final IResultReceiver receiver;
690         public final int userHandle;
691         public boolean haveResult = false;
692         public Bundle result = null;
693         public AssistStructure structure = null;
694         public AssistContent content = null;
695         public Bundle receiverExtras;
696
697         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699             activity = _activity;
700             extras = _extras;
701             intent = _intent;
702             hint = _hint;
703             receiver = _receiver;
704             receiverExtras = _receiverExtras;
705             userHandle = _userHandle;
706         }
707         @Override
708         public void run() {
709             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710             synchronized (this) {
711                 haveResult = true;
712                 notifyAll();
713             }
714             pendingAssistExtrasTimedOut(this);
715         }
716     }
717
718     final ArrayList<PendingAssistExtras> mPendingAssistExtras
719             = new ArrayList<PendingAssistExtras>();
720
721     /**
722      * Process management.
723      */
724     final ProcessList mProcessList = new ProcessList();
725
726     /**
727      * All of the applications we currently have running organized by name.
728      * The keys are strings of the application package name (as
729      * returned by the package manager), and the keys are ApplicationRecord
730      * objects.
731      */
732     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734     /**
735      * Tracking long-term execution of processes to look for abuse and other
736      * bad app behavior.
737      */
738     final ProcessStatsService mProcessStats;
739
740     /**
741      * The currently running isolated processes.
742      */
743     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745     /**
746      * Counter for assigning isolated process uids, to avoid frequently reusing the
747      * same ones.
748      */
749     int mNextIsolatedProcessUid = 0;
750
751     /**
752      * The currently running heavy-weight process, if any.
753      */
754     ProcessRecord mHeavyWeightProcess = null;
755
756     /**
757      * All of the processes we currently have running organized by pid.
758      * The keys are the pid running the application.
759      *
760      * <p>NOTE: This object is protected by its own lock, NOT the global
761      * activity manager lock!
762      */
763     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765     /**
766      * All of the processes that have been forced to be foreground.  The key
767      * is the pid of the caller who requested it (we hold a death
768      * link on it).
769      */
770     abstract class ForegroundToken implements IBinder.DeathRecipient {
771         int pid;
772         IBinder token;
773     }
774     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776     /**
777      * List of records for processes that someone had tried to start before the
778      * system was ready.  We don't start them at that point, but ensure they
779      * are started by the time booting is complete.
780      */
781     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783     /**
784      * List of persistent applications that are in the process
785      * of being started.
786      */
787     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789     /**
790      * Processes that are being forcibly torn down.
791      */
792     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794     /**
795      * List of running applications, sorted by recent usage.
796      * The first entry in the list is the least recently used.
797      */
798     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800     /**
801      * Where in mLruProcesses that the processes hosting activities start.
802      */
803     int mLruProcessActivityStart = 0;
804
805     /**
806      * Where in mLruProcesses that the processes hosting services start.
807      * This is after (lower index) than mLruProcessesActivityStart.
808      */
809     int mLruProcessServiceStart = 0;
810
811     /**
812      * List of processes that should gc as soon as things are idle.
813      */
814     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816     /**
817      * Processes we want to collect PSS data from.
818      */
819     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821     private boolean mBinderTransactionTrackingEnabled = false;
822
823     /**
824      * Last time we requested PSS data of all processes.
825      */
826     long mLastFullPssTime = SystemClock.uptimeMillis();
827
828     /**
829      * If set, the next time we collect PSS data we should do a full collection
830      * with data from native processes and the kernel.
831      */
832     boolean mFullPssPending = false;
833
834     /**
835      * This is the process holding what we currently consider to be
836      * the "home" activity.
837      */
838     ProcessRecord mHomeProcess;
839
840     /**
841      * This is the process holding the activity the user last visited that
842      * is in a different process from the one they are currently in.
843      */
844     ProcessRecord mPreviousProcess;
845
846     /**
847      * The time at which the previous process was last visible.
848      */
849     long mPreviousProcessVisibleTime;
850
851     /**
852      * Track all uids that have actively running processes.
853      */
854     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856     /**
857      * This is for verifying the UID report flow.
858      */
859     static final boolean VALIDATE_UID_STATES = true;
860     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862     /**
863      * Packages that the user has asked to have run in screen size
864      * compatibility mode instead of filling the screen.
865      */
866     final CompatModePackages mCompatModePackages;
867
868     /**
869      * Set of IntentSenderRecord objects that are currently active.
870      */
871     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874     /**
875      * Fingerprints (hashCode()) of stack traces that we've
876      * already logged DropBox entries for.  Guarded by itself.  If
877      * something (rogue user app) forces this over
878      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879      */
880     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883     /**
884      * Strict Mode background batched logging state.
885      *
886      * The string buffer is guarded by itself, and its lock is also
887      * used to determine if another batched write is already
888      * in-flight.
889      */
890     private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892     /**
893      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895      */
896     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898     /**
899      * Resolver for broadcast intents to registered receivers.
900      * Holds BroadcastFilter (subclass of IntentFilter).
901      */
902     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904         @Override
905         protected boolean allowFilterResult(
906                 BroadcastFilter filter, List<BroadcastFilter> dest) {
907             IBinder target = filter.receiverList.receiver.asBinder();
908             for (int i = dest.size() - 1; i >= 0; i--) {
909                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                     return false;
911                 }
912             }
913             return true;
914         }
915
916         @Override
917         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                     || userId == filter.owningUserId) {
920                 return super.newResult(filter, match, userId);
921             }
922             return null;
923         }
924
925         @Override
926         protected BroadcastFilter[] newArray(int size) {
927             return new BroadcastFilter[size];
928         }
929
930         @Override
931         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932             return packageName.equals(filter.packageName);
933         }
934     };
935
936     /**
937      * State of all active sticky broadcasts per user.  Keys are the action of the
938      * sticky Intent, values are an ArrayList of all broadcasted intents with
939      * that action (which should usually be one).  The SparseArray is keyed
940      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941      * for stickies that are sent to all users.
942      */
943     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946     final ActiveServices mServices;
947
948     final static class Association {
949         final int mSourceUid;
950         final String mSourceProcess;
951         final int mTargetUid;
952         final ComponentName mTargetComponent;
953         final String mTargetProcess;
954
955         int mCount;
956         long mTime;
957
958         int mNesting;
959         long mStartTime;
960
961         // states of the source process when the bind occurred.
962         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963         long mLastStateUptime;
964         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                 - ActivityManager.MIN_PROCESS_STATE+1];
966
967         Association(int sourceUid, String sourceProcess, int targetUid,
968                 ComponentName targetComponent, String targetProcess) {
969             mSourceUid = sourceUid;
970             mSourceProcess = sourceProcess;
971             mTargetUid = targetUid;
972             mTargetComponent = targetComponent;
973             mTargetProcess = targetProcess;
974         }
975     }
976
977     /**
978      * When service association tracking is enabled, this is all of the associations we
979      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980      * -> association data.
981      */
982     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983             mAssociations = new SparseArray<>();
984     boolean mTrackingAssociations;
985
986     /**
987      * Backup/restore process management
988      */
989     String mBackupAppName = null;
990     BackupRecord mBackupTarget = null;
991
992     final ProviderMap mProviderMap;
993
994     /**
995      * List of content providers who have clients waiting for them.  The
996      * application is currently being launched and the provider will be
997      * removed from this list once it is published.
998      */
999     final ArrayList<ContentProviderRecord> mLaunchingProviders
1000             = new ArrayList<ContentProviderRecord>();
1001
1002     /**
1003      * File storing persisted {@link #mGrantedUriPermissions}.
1004      */
1005     private final AtomicFile mGrantFile;
1006
1007     /** XML constants used in {@link #mGrantFile} */
1008     private static final String TAG_URI_GRANTS = "uri-grants";
1009     private static final String TAG_URI_GRANT = "uri-grant";
1010     private static final String ATTR_USER_HANDLE = "userHandle";
1011     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014     private static final String ATTR_TARGET_PKG = "targetPkg";
1015     private static final String ATTR_URI = "uri";
1016     private static final String ATTR_MODE_FLAGS = "modeFlags";
1017     private static final String ATTR_CREATED_TIME = "createdTime";
1018     private static final String ATTR_PREFIX = "prefix";
1019
1020     /**
1021      * Global set of specific {@link Uri} permissions that have been granted.
1022      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023      * to {@link UriPermission#uri} to {@link UriPermission}.
1024      */
1025     @GuardedBy("this")
1026     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029     public static class GrantUri {
1030         public final int sourceUserId;
1031         public final Uri uri;
1032         public boolean prefix;
1033
1034         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035             this.sourceUserId = sourceUserId;
1036             this.uri = uri;
1037             this.prefix = prefix;
1038         }
1039
1040         @Override
1041         public int hashCode() {
1042             int hashCode = 1;
1043             hashCode = 31 * hashCode + sourceUserId;
1044             hashCode = 31 * hashCode + uri.hashCode();
1045             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046             return hashCode;
1047         }
1048
1049         @Override
1050         public boolean equals(Object o) {
1051             if (o instanceof GrantUri) {
1052                 GrantUri other = (GrantUri) o;
1053                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                         && prefix == other.prefix;
1055             }
1056             return false;
1057         }
1058
1059         @Override
1060         public String toString() {
1061             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062             if (prefix) result += " [prefix]";
1063             return result;
1064         }
1065
1066         public String toSafeString() {
1067             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068             if (prefix) result += " [prefix]";
1069             return result;
1070         }
1071
1072         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                     ContentProvider.getUriWithoutUserId(uri), false);
1075         }
1076     }
1077
1078     CoreSettingsObserver mCoreSettingsObserver;
1079
1080     FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082     private final class FontScaleSettingObserver extends ContentObserver {
1083         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085         public FontScaleSettingObserver() {
1086             super(mHandler);
1087             ContentResolver resolver = mContext.getContentResolver();
1088             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089         }
1090
1091         @Override
1092         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093             if (mFontScaleUri.equals(uri)) {
1094                 updateFontScaleIfNeeded(userId);
1095             }
1096         }
1097     }
1098
1099     /**
1100      * Thread-local storage used to carry caller permissions over through
1101      * indirect content-provider access.
1102      */
1103     private class Identity {
1104         public final IBinder token;
1105         public final int pid;
1106         public final int uid;
1107
1108         Identity(IBinder _token, int _pid, int _uid) {
1109             token = _token;
1110             pid = _pid;
1111             uid = _uid;
1112         }
1113     }
1114
1115     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117     /**
1118      * All information we have collected about the runtime performance of
1119      * any user id that can impact battery performance.
1120      */
1121     final BatteryStatsService mBatteryStatsService;
1122
1123     /**
1124      * Information about component usage
1125      */
1126     UsageStatsManagerInternal mUsageStatsService;
1127
1128     /**
1129      * Access to DeviceIdleController service.
1130      */
1131     DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133     /**
1134      * Information about and control over application operations
1135      */
1136     final AppOpsService mAppOpsService;
1137
1138     /**
1139      * Current configuration information.  HistoryRecord objects are given
1140      * a reference to this object to indicate which configuration they are
1141      * currently running in, so this object must be kept immutable.
1142      */
1143     Configuration mConfiguration = new Configuration();
1144
1145     /**
1146      * Current sequencing integer of the configuration, for skipping old
1147      * configurations.
1148      */
1149     int mConfigurationSeq = 0;
1150
1151     boolean mSuppressResizeConfigChanges = false;
1152
1153     /**
1154      * Hardware-reported OpenGLES version.
1155      */
1156     final int GL_ES_VERSION;
1157
1158     /**
1159      * List of initialization arguments to pass to all processes when binding applications to them.
1160      * For example, references to the commonly used services.
1161      */
1162     HashMap<String, IBinder> mAppBindArgs;
1163     HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165     /**
1166      * Temporary to avoid allocations.  Protected by main lock.
1167      */
1168     final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170     /**
1171      * Used to control how we initialize the service.
1172      */
1173     ComponentName mTopComponent;
1174     String mTopAction = Intent.ACTION_MAIN;
1175     String mTopData;
1176
1177     volatile boolean mProcessesReady = false;
1178     volatile boolean mSystemReady = false;
1179     volatile boolean mOnBattery = false;
1180     volatile int mFactoryTest;
1181
1182     @GuardedBy("this") boolean mBooting = false;
1183     @GuardedBy("this") boolean mCallFinishBooting = false;
1184     @GuardedBy("this") boolean mBootAnimationComplete = false;
1185     @GuardedBy("this") boolean mLaunchWarningShown = false;
1186     @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188     Context mContext;
1189
1190     /**
1191      * The time at which we will allow normal application switches again,
1192      * after a call to {@link #stopAppSwitches()}.
1193      */
1194     long mAppSwitchesAllowedTime;
1195
1196     /**
1197      * This is set to true after the first switch after mAppSwitchesAllowedTime
1198      * is set; any switches after that will clear the time.
1199      */
1200     boolean mDidAppSwitch;
1201
1202     /**
1203      * Last time (in realtime) at which we checked for power usage.
1204      */
1205     long mLastPowerCheckRealtime;
1206
1207     /**
1208      * Last time (in uptime) at which we checked for power usage.
1209      */
1210     long mLastPowerCheckUptime;
1211
1212     /**
1213      * Set while we are wanting to sleep, to prevent any
1214      * activities from being started/resumed.
1215      *
1216      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1217      *
1218      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1219      * while in the sleep state until there is a pending transition out of sleep, in which case
1220      * mSleeping is set to false, and remains false while awake.
1221      *
1222      * Whether mSleeping can quickly toggled between true/false without the device actually
1223      * display changing states is undefined.
1224      */
1225     private boolean mSleeping = false;
1226
1227     /**
1228      * The process state used for processes that are running the top activities.
1229      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1230      */
1231     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1232
1233     /**
1234      * Set while we are running a voice interaction.  This overrides
1235      * sleeping while it is active.
1236      */
1237     private IVoiceInteractionSession mRunningVoice;
1238
1239     /**
1240      * For some direct access we need to power manager.
1241      */
1242     PowerManagerInternal mLocalPowerManager;
1243
1244     /**
1245      * We want to hold a wake lock while running a voice interaction session, since
1246      * this may happen with the screen off and we need to keep the CPU running to
1247      * be able to continue to interact with the user.
1248      */
1249     PowerManager.WakeLock mVoiceWakeLock;
1250
1251     /**
1252      * State of external calls telling us if the device is awake or asleep.
1253      */
1254     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1255
1256     /**
1257      * A list of tokens that cause the top activity to be put to sleep.
1258      * They are used by components that may hide and block interaction with underlying
1259      * activities.
1260      */
1261     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1262
1263     static final int LOCK_SCREEN_HIDDEN = 0;
1264     static final int LOCK_SCREEN_LEAVING = 1;
1265     static final int LOCK_SCREEN_SHOWN = 2;
1266     /**
1267      * State of external call telling us if the lock screen is shown.
1268      */
1269     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1270
1271     /**
1272      * Set if we are shutting down the system, similar to sleeping.
1273      */
1274     boolean mShuttingDown = false;
1275
1276     /**
1277      * Current sequence id for oom_adj computation traversal.
1278      */
1279     int mAdjSeq = 0;
1280
1281     /**
1282      * Current sequence id for process LRU updating.
1283      */
1284     int mLruSeq = 0;
1285
1286     /**
1287      * Keep track of the non-cached/empty process we last found, to help
1288      * determine how to distribute cached/empty processes next time.
1289      */
1290     int mNumNonCachedProcs = 0;
1291
1292     /**
1293      * Keep track of the number of cached hidden procs, to balance oom adj
1294      * distribution between those and empty procs.
1295      */
1296     int mNumCachedHiddenProcs = 0;
1297
1298     /**
1299      * Keep track of the number of service processes we last found, to
1300      * determine on the next iteration which should be B services.
1301      */
1302     int mNumServiceProcs = 0;
1303     int mNewNumAServiceProcs = 0;
1304     int mNewNumServiceProcs = 0;
1305
1306     /**
1307      * Allow the current computed overall memory level of the system to go down?
1308      * This is set to false when we are killing processes for reasons other than
1309      * memory management, so that the now smaller process list will not be taken as
1310      * an indication that memory is tighter.
1311      */
1312     boolean mAllowLowerMemLevel = false;
1313
1314     /**
1315      * The last computed memory level, for holding when we are in a state that
1316      * processes are going away for other reasons.
1317      */
1318     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1319
1320     /**
1321      * The last total number of process we have, to determine if changes actually look
1322      * like a shrinking number of process due to lower RAM.
1323      */
1324     int mLastNumProcesses;
1325
1326     /**
1327      * The uptime of the last time we performed idle maintenance.
1328      */
1329     long mLastIdleTime = SystemClock.uptimeMillis();
1330
1331     /**
1332      * Total time spent with RAM that has been added in the past since the last idle time.
1333      */
1334     long mLowRamTimeSinceLastIdle = 0;
1335
1336     /**
1337      * If RAM is currently low, when that horrible situation started.
1338      */
1339     long mLowRamStartTime = 0;
1340
1341     /**
1342      * For reporting to battery stats the current top application.
1343      */
1344     private String mCurResumedPackage = null;
1345     private int mCurResumedUid = -1;
1346
1347     /**
1348      * For reporting to battery stats the apps currently running foreground
1349      * service.  The ProcessMap is package/uid tuples; each of these contain
1350      * an array of the currently foreground processes.
1351      */
1352     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1353             = new ProcessMap<ArrayList<ProcessRecord>>();
1354
1355     /**
1356      * This is set if we had to do a delayed dexopt of an app before launching
1357      * it, to increase the ANR timeouts in that case.
1358      */
1359     boolean mDidDexOpt;
1360
1361     /**
1362      * Set if the systemServer made a call to enterSafeMode.
1363      */
1364     boolean mSafeMode;
1365
1366     /**
1367      * If true, we are running under a test environment so will sample PSS from processes
1368      * much more rapidly to try to collect better data when the tests are rapidly
1369      * running through apps.
1370      */
1371     boolean mTestPssMode = false;
1372
1373     String mDebugApp = null;
1374     boolean mWaitForDebugger = false;
1375     boolean mDebugTransient = false;
1376     String mOrigDebugApp = null;
1377     boolean mOrigWaitForDebugger = false;
1378     boolean mAlwaysFinishActivities = false;
1379     boolean mLenientBackgroundCheck = false;
1380     boolean mForceResizableActivities;
1381     boolean mSupportsMultiWindow;
1382     boolean mSupportsFreeformWindowManagement;
1383     boolean mSupportsPictureInPicture;
1384     boolean mSupportsLeanbackOnly;
1385     Rect mDefaultPinnedStackBounds;
1386     IActivityController mController = null;
1387     boolean mControllerIsAMonkey = false;
1388     String mProfileApp = null;
1389     ProcessRecord mProfileProc = null;
1390     String mProfileFile;
1391     ParcelFileDescriptor mProfileFd;
1392     int mSamplingInterval = 0;
1393     boolean mAutoStopProfiler = false;
1394     int mProfileType = 0;
1395     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1396     String mMemWatchDumpProcName;
1397     String mMemWatchDumpFile;
1398     int mMemWatchDumpPid;
1399     int mMemWatchDumpUid;
1400     String mTrackAllocationApp = null;
1401     String mNativeDebuggingApp = null;
1402
1403     final long[] mTmpLong = new long[2];
1404
1405     static final class ProcessChangeItem {
1406         static final int CHANGE_ACTIVITIES = 1<<0;
1407         static final int CHANGE_PROCESS_STATE = 1<<1;
1408         int changes;
1409         int uid;
1410         int pid;
1411         int processState;
1412         boolean foregroundActivities;
1413     }
1414
1415     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1416     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1417
1418     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1419     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1420
1421     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1422     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1423
1424     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1425     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1426
1427     /**
1428      * Runtime CPU use collection thread.  This object's lock is used to
1429      * perform synchronization with the thread (notifying it to run).
1430      */
1431     final Thread mProcessCpuThread;
1432
1433     /**
1434      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1435      * Must acquire this object's lock when accessing it.
1436      * NOTE: this lock will be held while doing long operations (trawling
1437      * through all processes in /proc), so it should never be acquired by
1438      * any critical paths such as when holding the main activity manager lock.
1439      */
1440     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1441             MONITOR_THREAD_CPU_USAGE);
1442     final AtomicLong mLastCpuTime = new AtomicLong(0);
1443     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1444
1445     long mLastWriteTime = 0;
1446
1447     /**
1448      * Used to retain an update lock when the foreground activity is in
1449      * immersive mode.
1450      */
1451     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1452
1453     /**
1454      * Set to true after the system has finished booting.
1455      */
1456     boolean mBooted = false;
1457
1458     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1459     int mProcessLimitOverride = -1;
1460
1461     WindowManagerService mWindowManager;
1462     final ActivityThread mSystemThread;
1463
1464     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1465         final ProcessRecord mApp;
1466         final int mPid;
1467         final IApplicationThread mAppThread;
1468
1469         AppDeathRecipient(ProcessRecord app, int pid,
1470                 IApplicationThread thread) {
1471             if (DEBUG_ALL) Slog.v(
1472                 TAG, "New death recipient " + this
1473                 + " for thread " + thread.asBinder());
1474             mApp = app;
1475             mPid = pid;
1476             mAppThread = thread;
1477         }
1478
1479         @Override
1480         public void binderDied() {
1481             if (DEBUG_ALL) Slog.v(
1482                 TAG, "Death received in " + this
1483                 + " for thread " + mAppThread.asBinder());
1484             synchronized(ActivityManagerService.this) {
1485                 appDiedLocked(mApp, mPid, mAppThread, true);
1486             }
1487         }
1488     }
1489
1490     static final int SHOW_ERROR_UI_MSG = 1;
1491     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1492     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1493     static final int UPDATE_CONFIGURATION_MSG = 4;
1494     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1495     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1496     static final int SERVICE_TIMEOUT_MSG = 12;
1497     static final int UPDATE_TIME_ZONE = 13;
1498     static final int SHOW_UID_ERROR_UI_MSG = 14;
1499     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1500     static final int PROC_START_TIMEOUT_MSG = 20;
1501     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1502     static final int KILL_APPLICATION_MSG = 22;
1503     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1504     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1505     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1506     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1507     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1508     static final int CLEAR_DNS_CACHE_MSG = 28;
1509     static final int UPDATE_HTTP_PROXY_MSG = 29;
1510     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1511     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1512     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1513     static final int REPORT_MEM_USAGE_MSG = 33;
1514     static final int REPORT_USER_SWITCH_MSG = 34;
1515     static final int CONTINUE_USER_SWITCH_MSG = 35;
1516     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1517     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1518     static final int PERSIST_URI_GRANTS_MSG = 38;
1519     static final int REQUEST_ALL_PSS_MSG = 39;
1520     static final int START_PROFILES_MSG = 40;
1521     static final int UPDATE_TIME = 41;
1522     static final int SYSTEM_USER_START_MSG = 42;
1523     static final int SYSTEM_USER_CURRENT_MSG = 43;
1524     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1525     static final int FINISH_BOOTING_MSG = 45;
1526     static final int START_USER_SWITCH_UI_MSG = 46;
1527     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1528     static final int DISMISS_DIALOG_UI_MSG = 48;
1529     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1530     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1531     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1532     static final int DELETE_DUMPHEAP_MSG = 52;
1533     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1534     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1535     static final int REPORT_TIME_TRACKER_MSG = 55;
1536     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1537     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1538     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1539     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1540     static final int IDLE_UIDS_MSG = 60;
1541     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1542     static final int LOG_STACK_STATE = 62;
1543     static final int VR_MODE_CHANGE_MSG = 63;
1544     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1545     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1546     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1547     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1548     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1549     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
1550     static final int NOTIFY_VR_SLEEPING_MSG = 70;
1551
1552     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554     static final int FIRST_COMPAT_MODE_MSG = 300;
1555     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1556
1557     static ServiceThread sKillThread = null;
1558     static KillHandler sKillHandler = null;
1559
1560     CompatModeDialog mCompatModeDialog;
1561     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562     long mLastMemUsageReportTime = 0;
1563
1564     /**
1565      * Flag whether the current user is a "monkey", i.e. whether
1566      * the UI is driven by a UI automation tool.
1567      */
1568     private boolean mUserIsMonkey;
1569
1570     /** Flag whether the device has a Recents UI */
1571     boolean mHasRecents;
1572
1573     /** The dimensions of the thumbnails in the Recents UI. */
1574     int mThumbnailWidth;
1575     int mThumbnailHeight;
1576     float mFullscreenThumbnailScale;
1577
1578     final ServiceThread mHandlerThread;
1579     final MainHandler mHandler;
1580     final UiHandler mUiHandler;
1581
1582     PackageManagerInternal mPackageManagerInt;
1583
1584     // VoiceInteraction session ID that changes for each new request except when
1585     // being called for multiwindow assist in a single session.
1586     private int mViSessionId = 1000;
1587
1588     final boolean mPermissionReviewRequired;
1589
1590     final class KillHandler extends Handler {
1591         static final int KILL_PROCESS_GROUP_MSG = 4000;
1592
1593         public KillHandler(Looper looper) {
1594             super(looper, null, true);
1595         }
1596
1597         @Override
1598         public void handleMessage(Message msg) {
1599             switch (msg.what) {
1600                 case KILL_PROCESS_GROUP_MSG:
1601                 {
1602                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1605                 }
1606                 break;
1607
1608                 default:
1609                     super.handleMessage(msg);
1610             }
1611         }
1612     }
1613
1614     final class UiHandler extends Handler {
1615         public UiHandler() {
1616             super(com.android.server.UiThread.get().getLooper(), null, true);
1617         }
1618
1619         @Override
1620         public void handleMessage(Message msg) {
1621             switch (msg.what) {
1622             case SHOW_ERROR_UI_MSG: {
1623                 mAppErrors.handleShowAppErrorUi(msg);
1624                 ensureBootCompleted();
1625             } break;
1626             case SHOW_NOT_RESPONDING_UI_MSG: {
1627                 mAppErrors.handleShowAnrUi(msg);
1628                 ensureBootCompleted();
1629             } break;
1630             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632                 synchronized (ActivityManagerService.this) {
1633                     ProcessRecord proc = (ProcessRecord) data.get("app");
1634                     if (proc == null) {
1635                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1636                         break;
1637                     }
1638                     if (proc.crashDialog != null) {
1639                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1640                         return;
1641                     }
1642                     AppErrorResult res = (AppErrorResult) data.get("result");
1643                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644                         Dialog d = new StrictModeViolationDialog(mContext,
1645                                 ActivityManagerService.this, res, proc);
1646                         d.show();
1647                         proc.crashDialog = d;
1648                     } else {
1649                         // The device is asleep, so just pretend that the user
1650                         // saw a crash dialog and hit "force quit".
1651                         res.set(0);
1652                     }
1653                 }
1654                 ensureBootCompleted();
1655             } break;
1656             case SHOW_FACTORY_ERROR_UI_MSG: {
1657                 Dialog d = new FactoryErrorDialog(
1658                     mContext, msg.getData().getCharSequence("msg"));
1659                 d.show();
1660                 ensureBootCompleted();
1661             } break;
1662             case WAIT_FOR_DEBUGGER_UI_MSG: {
1663                 synchronized (ActivityManagerService.this) {
1664                     ProcessRecord app = (ProcessRecord)msg.obj;
1665                     if (msg.arg1 != 0) {
1666                         if (!app.waitedForDebugger) {
1667                             Dialog d = new AppWaitingForDebuggerDialog(
1668                                     ActivityManagerService.this,
1669                                     mContext, app);
1670                             app.waitDialog = d;
1671                             app.waitedForDebugger = true;
1672                             d.show();
1673                         }
1674                     } else {
1675                         if (app.waitDialog != null) {
1676                             app.waitDialog.dismiss();
1677                             app.waitDialog = null;
1678                         }
1679                     }
1680                 }
1681             } break;
1682             case SHOW_UID_ERROR_UI_MSG: {
1683                 if (mShowDialogs) {
1684                     AlertDialog d = new BaseErrorDialog(mContext);
1685                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                     d.setCancelable(false);
1687                     d.setTitle(mContext.getText(R.string.android_system_label));
1688                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                     d.show();
1692                 }
1693             } break;
1694             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1695                 if (mShowDialogs) {
1696                     AlertDialog d = new BaseErrorDialog(mContext);
1697                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                     d.setCancelable(false);
1699                     d.setTitle(mContext.getText(R.string.android_system_label));
1700                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                     d.show();
1704                 }
1705             } break;
1706             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707                 synchronized (ActivityManagerService.this) {
1708                     ActivityRecord ar = (ActivityRecord) msg.obj;
1709                     if (mCompatModeDialog != null) {
1710                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1711                                 ar.info.applicationInfo.packageName)) {
1712                             return;
1713                         }
1714                         mCompatModeDialog.dismiss();
1715                         mCompatModeDialog = null;
1716                     }
1717                     if (ar != null && false) {
1718                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1719                                 ar.packageName)) {
1720                             int mode = mCompatModePackages.computeCompatModeLocked(
1721                                     ar.info.applicationInfo);
1722                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724                                 mCompatModeDialog = new CompatModeDialog(
1725                                         ActivityManagerService.this, mContext,
1726                                         ar.info.applicationInfo);
1727                                 mCompatModeDialog.show();
1728                             }
1729                         }
1730                     }
1731                 }
1732                 break;
1733             }
1734             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735                 synchronized (ActivityManagerService.this) {
1736                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1737                     if (mUnsupportedDisplaySizeDialog != null) {
1738                         mUnsupportedDisplaySizeDialog.dismiss();
1739                         mUnsupportedDisplaySizeDialog = null;
1740                     }
1741                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1742                             ar.packageName)) {
1743                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1744                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1745                         mUnsupportedDisplaySizeDialog.show();
1746                     }
1747                 }
1748                 break;
1749             }
1750             case START_USER_SWITCH_UI_MSG: {
1751                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1752                 break;
1753             }
1754             case DISMISS_DIALOG_UI_MSG: {
1755                 final Dialog d = (Dialog) msg.obj;
1756                 d.dismiss();
1757                 break;
1758             }
1759             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1760                 dispatchProcessesChanged();
1761                 break;
1762             }
1763             case DISPATCH_PROCESS_DIED_UI_MSG: {
1764                 final int pid = msg.arg1;
1765                 final int uid = msg.arg2;
1766                 dispatchProcessDied(pid, uid);
1767                 break;
1768             }
1769             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1770                 dispatchUidsChanged();
1771             } break;
1772             }
1773         }
1774     }
1775
1776     final class MainHandler extends Handler {
1777         public MainHandler(Looper looper) {
1778             super(looper, null, true);
1779         }
1780
1781         @Override
1782         public void handleMessage(Message msg) {
1783             switch (msg.what) {
1784             case UPDATE_CONFIGURATION_MSG: {
1785                 final ContentResolver resolver = mContext.getContentResolver();
1786                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1787                         msg.arg1);
1788             } break;
1789             case GC_BACKGROUND_PROCESSES_MSG: {
1790                 synchronized (ActivityManagerService.this) {
1791                     performAppGcsIfAppropriateLocked();
1792                 }
1793             } break;
1794             case SERVICE_TIMEOUT_MSG: {
1795                 if (mDidDexOpt) {
1796                     mDidDexOpt = false;
1797                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1798                     nmsg.obj = msg.obj;
1799                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1800                     return;
1801                 }
1802                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1803             } break;
1804             case UPDATE_TIME_ZONE: {
1805                 synchronized (ActivityManagerService.this) {
1806                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                         ProcessRecord r = mLruProcesses.get(i);
1808                         if (r.thread != null) {
1809                             try {
1810                                 r.thread.updateTimeZone();
1811                             } catch (RemoteException ex) {
1812                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1813                             }
1814                         }
1815                     }
1816                 }
1817             } break;
1818             case CLEAR_DNS_CACHE_MSG: {
1819                 synchronized (ActivityManagerService.this) {
1820                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821                         ProcessRecord r = mLruProcesses.get(i);
1822                         if (r.thread != null) {
1823                             try {
1824                                 r.thread.clearDnsCache();
1825                             } catch (RemoteException ex) {
1826                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1827                             }
1828                         }
1829                     }
1830                 }
1831             } break;
1832             case UPDATE_HTTP_PROXY_MSG: {
1833                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1834                 String host = "";
1835                 String port = "";
1836                 String exclList = "";
1837                 Uri pacFileUrl = Uri.EMPTY;
1838                 if (proxy != null) {
1839                     host = proxy.getHost();
1840                     port = Integer.toString(proxy.getPort());
1841                     exclList = proxy.getExclusionListAsString();
1842                     pacFileUrl = proxy.getPacFileUrl();
1843                 }
1844                 synchronized (ActivityManagerService.this) {
1845                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846                         ProcessRecord r = mLruProcesses.get(i);
1847                         if (r.thread != null) {
1848                             try {
1849                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1850                             } catch (RemoteException ex) {
1851                                 Slog.w(TAG, "Failed to update http proxy for: " +
1852                                         r.info.processName);
1853                             }
1854                         }
1855                     }
1856                 }
1857             } break;
1858             case PROC_START_TIMEOUT_MSG: {
1859                 if (mDidDexOpt) {
1860                     mDidDexOpt = false;
1861                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1862                     nmsg.obj = msg.obj;
1863                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1864                     return;
1865                 }
1866                 ProcessRecord app = (ProcessRecord)msg.obj;
1867                 synchronized (ActivityManagerService.this) {
1868                     processStartTimedOutLocked(app);
1869                 }
1870             } break;
1871             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1872                 ProcessRecord app = (ProcessRecord)msg.obj;
1873                 synchronized (ActivityManagerService.this) {
1874                     processContentProviderPublishTimedOutLocked(app);
1875                 }
1876             } break;
1877             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1878                 synchronized (ActivityManagerService.this) {
1879                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1880                 }
1881             } break;
1882             case KILL_APPLICATION_MSG: {
1883                 synchronized (ActivityManagerService.this) {
1884                     final int appId = msg.arg1;
1885                     final int userId = msg.arg2;
1886                     Bundle bundle = (Bundle)msg.obj;
1887                     String pkg = bundle.getString("pkg");
1888                     String reason = bundle.getString("reason");
1889                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1890                             false, userId, reason);
1891                 }
1892             } break;
1893             case FINALIZE_PENDING_INTENT_MSG: {
1894                 ((PendingIntentRecord)msg.obj).completeFinalize();
1895             } break;
1896             case POST_HEAVY_NOTIFICATION_MSG: {
1897                 INotificationManager inm = NotificationManager.getService();
1898                 if (inm == null) {
1899                     return;
1900                 }
1901
1902                 ActivityRecord root = (ActivityRecord)msg.obj;
1903                 ProcessRecord process = root.app;
1904                 if (process == null) {
1905                     return;
1906                 }
1907
1908                 try {
1909                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1910                     String text = mContext.getString(R.string.heavy_weight_notification,
1911                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1912                     Notification notification = new Notification.Builder(context)
1913                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1914                             .setWhen(0)
1915                             .setOngoing(true)
1916                             .setTicker(text)
1917                             .setColor(mContext.getColor(
1918                                     com.android.internal.R.color.system_notification_accent_color))
1919                             .setContentTitle(text)
1920                             .setContentText(
1921                                     mContext.getText(R.string.heavy_weight_notification_detail))
1922                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1923                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1924                                     new UserHandle(root.userId)))
1925                             .build();
1926                     try {
1927                         int[] outId = new int[1];
1928                         inm.enqueueNotificationWithTag("android", "android", null,
1929                                 R.string.heavy_weight_notification,
1930                                 notification, outId, root.userId);
1931                     } catch (RuntimeException e) {
1932                         Slog.w(ActivityManagerService.TAG,
1933                                 "Error showing notification for heavy-weight app", e);
1934                     } catch (RemoteException e) {
1935                     }
1936                 } catch (NameNotFoundException e) {
1937                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1938                 }
1939             } break;
1940             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1941                 INotificationManager inm = NotificationManager.getService();
1942                 if (inm == null) {
1943                     return;
1944                 }
1945                 try {
1946                     inm.cancelNotificationWithTag("android", null,
1947                             R.string.heavy_weight_notification,  msg.arg1);
1948                 } catch (RuntimeException e) {
1949                     Slog.w(ActivityManagerService.TAG,
1950                             "Error canceling notification for service", e);
1951                 } catch (RemoteException e) {
1952                 }
1953             } break;
1954             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1955                 synchronized (ActivityManagerService.this) {
1956                     checkExcessivePowerUsageLocked(true);
1957                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1958                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1960                 }
1961             } break;
1962             case REPORT_MEM_USAGE_MSG: {
1963                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1964                 Thread thread = new Thread() {
1965                     @Override public void run() {
1966                         reportMemUsage(memInfos);
1967                     }
1968                 };
1969                 thread.start();
1970                 break;
1971             }
1972             case REPORT_USER_SWITCH_MSG: {
1973                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1974                 break;
1975             }
1976             case CONTINUE_USER_SWITCH_MSG: {
1977                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1978                 break;
1979             }
1980             case USER_SWITCH_TIMEOUT_MSG: {
1981                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1982                 break;
1983             }
1984             case IMMERSIVE_MODE_LOCK_MSG: {
1985                 final boolean nextState = (msg.arg1 != 0);
1986                 if (mUpdateLock.isHeld() != nextState) {
1987                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1988                             "Applying new update lock state '" + nextState
1989                             + "' for " + (ActivityRecord)msg.obj);
1990                     if (nextState) {
1991                         mUpdateLock.acquire();
1992                     } else {
1993                         mUpdateLock.release();
1994                     }
1995                 }
1996                 break;
1997             }
1998             case PERSIST_URI_GRANTS_MSG: {
1999                 writeGrantedUriPermissions();
2000                 break;
2001             }
2002             case REQUEST_ALL_PSS_MSG: {
2003                 synchronized (ActivityManagerService.this) {
2004                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2005                 }
2006                 break;
2007             }
2008             case START_PROFILES_MSG: {
2009                 synchronized (ActivityManagerService.this) {
2010                     mUserController.startProfilesLocked();
2011                 }
2012                 break;
2013             }
2014             case UPDATE_TIME: {
2015                 synchronized (ActivityManagerService.this) {
2016                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2017                         ProcessRecord r = mLruProcesses.get(i);
2018                         if (r.thread != null) {
2019                             try {
2020                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2021                             } catch (RemoteException ex) {
2022                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2023                             }
2024                         }
2025                     }
2026                 }
2027                 break;
2028             }
2029             case SYSTEM_USER_START_MSG: {
2030                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2031                         Integer.toString(msg.arg1), msg.arg1);
2032                 mSystemServiceManager.startUser(msg.arg1);
2033                 break;
2034             }
2035             case SYSTEM_USER_UNLOCK_MSG: {
2036                 final int userId = msg.arg1;
2037                 mSystemServiceManager.unlockUser(userId);
2038                 synchronized (ActivityManagerService.this) {
2039                     mRecentTasks.loadUserRecentsLocked(userId);
2040                 }
2041                 if (userId == UserHandle.USER_SYSTEM) {
2042                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2043                 }
2044                 installEncryptionUnawareProviders(userId);
2045                 mUserController.finishUserUnlocked((UserState) msg.obj);
2046                 break;
2047             }
2048             case SYSTEM_USER_CURRENT_MSG: {
2049                 mBatteryStatsService.noteEvent(
2050                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2051                         Integer.toString(msg.arg2), msg.arg2);
2052                 mBatteryStatsService.noteEvent(
2053                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2054                         Integer.toString(msg.arg1), msg.arg1);
2055                 mSystemServiceManager.switchUser(msg.arg1);
2056                 break;
2057             }
2058             case ENTER_ANIMATION_COMPLETE_MSG: {
2059                 synchronized (ActivityManagerService.this) {
2060                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2061                     if (r != null && r.app != null && r.app.thread != null) {
2062                         try {
2063                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2064                         } catch (RemoteException e) {
2065                         }
2066                     }
2067                 }
2068                 break;
2069             }
2070             case FINISH_BOOTING_MSG: {
2071                 if (msg.arg1 != 0) {
2072                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2073                     finishBooting();
2074                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2075                 }
2076                 if (msg.arg2 != 0) {
2077                     enableScreenAfterBoot();
2078                 }
2079                 break;
2080             }
2081             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2082                 try {
2083                     Locale l = (Locale) msg.obj;
2084                     IBinder service = ServiceManager.getService("mount");
2085                     IMountService mountService = IMountService.Stub.asInterface(service);
2086                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2087                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2088                 } catch (RemoteException e) {
2089                     Log.e(TAG, "Error storing locale for decryption UI", e);
2090                 }
2091                 break;
2092             }
2093             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2094                 synchronized (ActivityManagerService.this) {
2095                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                         try {
2097                             // Make a one-way callback to the listener
2098                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2099                         } catch (RemoteException e){
2100                             // Handled by the RemoteCallbackList
2101                         }
2102                     }
2103                     mTaskStackListeners.finishBroadcast();
2104                 }
2105                 break;
2106             }
2107             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2108                 synchronized (ActivityManagerService.this) {
2109                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                         try {
2111                             // Make a one-way callback to the listener
2112                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2113                         } catch (RemoteException e){
2114                             // Handled by the RemoteCallbackList
2115                         }
2116                     }
2117                     mTaskStackListeners.finishBroadcast();
2118                 }
2119                 break;
2120             }
2121             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2122                 synchronized (ActivityManagerService.this) {
2123                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                         try {
2125                             // Make a one-way callback to the listener
2126                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2127                         } catch (RemoteException e){
2128                             // Handled by the RemoteCallbackList
2129                         }
2130                     }
2131                     mTaskStackListeners.finishBroadcast();
2132                 }
2133                 break;
2134             }
2135             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2136                 synchronized (ActivityManagerService.this) {
2137                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                         try {
2139                             // Make a one-way callback to the listener
2140                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2141                         } catch (RemoteException e){
2142                             // Handled by the RemoteCallbackList
2143                         }
2144                     }
2145                     mTaskStackListeners.finishBroadcast();
2146                 }
2147                 break;
2148             }
2149             case NOTIFY_FORCED_RESIZABLE_MSG: {
2150                 synchronized (ActivityManagerService.this) {
2151                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2152                         try {
2153                             // Make a one-way callback to the listener
2154                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2155                                     (String) msg.obj, msg.arg1);
2156                         } catch (RemoteException e){
2157                             // Handled by the RemoteCallbackList
2158                         }
2159                     }
2160                     mTaskStackListeners.finishBroadcast();
2161                 }
2162                 break;
2163             }
2164                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2165                     synchronized (ActivityManagerService.this) {
2166                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2167                             try {
2168                                 // Make a one-way callback to the listener
2169                                 mTaskStackListeners.getBroadcastItem(i)
2170                                         .onActivityDismissingDockedStack();
2171                             } catch (RemoteException e){
2172                                 // Handled by the RemoteCallbackList
2173                             }
2174                         }
2175                         mTaskStackListeners.finishBroadcast();
2176                     }
2177                     break;
2178                 }
2179             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2180                 final int uid = msg.arg1;
2181                 final byte[] firstPacket = (byte[]) msg.obj;
2182
2183                 synchronized (mPidsSelfLocked) {
2184                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2185                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2186                         if (p.uid == uid) {
2187                             try {
2188                                 p.thread.notifyCleartextNetwork(firstPacket);
2189                             } catch (RemoteException ignored) {
2190                             }
2191                         }
2192                     }
2193                 }
2194                 break;
2195             }
2196             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2197                 final String procName;
2198                 final int uid;
2199                 final long memLimit;
2200                 final String reportPackage;
2201                 synchronized (ActivityManagerService.this) {
2202                     procName = mMemWatchDumpProcName;
2203                     uid = mMemWatchDumpUid;
2204                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2205                     if (val == null) {
2206                         val = mMemWatchProcesses.get(procName, 0);
2207                     }
2208                     if (val != null) {
2209                         memLimit = val.first;
2210                         reportPackage = val.second;
2211                     } else {
2212                         memLimit = 0;
2213                         reportPackage = null;
2214                     }
2215                 }
2216                 if (procName == null) {
2217                     return;
2218                 }
2219
2220                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2221                         "Showing dump heap notification from " + procName + "/" + uid);
2222
2223                 INotificationManager inm = NotificationManager.getService();
2224                 if (inm == null) {
2225                     return;
2226                 }
2227
2228                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2229
2230
2231                 Intent deleteIntent = new Intent();
2232                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2233                 Intent intent = new Intent();
2234                 intent.setClassName("android", DumpHeapActivity.class.getName());
2235                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2236                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2237                 if (reportPackage != null) {
2238                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2239                 }
2240                 int userId = UserHandle.getUserId(uid);
2241                 Notification notification = new Notification.Builder(mContext)
2242                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2243                         .setWhen(0)
2244                         .setOngoing(true)
2245                         .setAutoCancel(true)
2246                         .setTicker(text)
2247                         .setColor(mContext.getColor(
2248                                 com.android.internal.R.color.system_notification_accent_color))
2249                         .setContentTitle(text)
2250                         .setContentText(
2251                                 mContext.getText(R.string.dump_heap_notification_detail))
2252                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2253                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2254                                 new UserHandle(userId)))
2255                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2256                                 deleteIntent, 0, UserHandle.SYSTEM))
2257                         .build();
2258
2259                 try {
2260                     int[] outId = new int[1];
2261                     inm.enqueueNotificationWithTag("android", "android", null,
2262                             R.string.dump_heap_notification,
2263                             notification, outId, userId);
2264                 } catch (RuntimeException e) {
2265                     Slog.w(ActivityManagerService.TAG,
2266                             "Error showing notification for dump heap", e);
2267                 } catch (RemoteException e) {
2268                 }
2269             } break;
2270             case DELETE_DUMPHEAP_MSG: {
2271                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2272                         DumpHeapActivity.JAVA_URI,
2273                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2274                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2275                         UserHandle.myUserId());
2276                 synchronized (ActivityManagerService.this) {
2277                     mMemWatchDumpFile = null;
2278                     mMemWatchDumpProcName = null;
2279                     mMemWatchDumpPid = -1;
2280                     mMemWatchDumpUid = -1;
2281                 }
2282             } break;
2283             case FOREGROUND_PROFILE_CHANGED_MSG: {
2284                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2285             } break;
2286             case REPORT_TIME_TRACKER_MSG: {
2287                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2288                 tracker.deliverResult(mContext);
2289             } break;
2290             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2291                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2292             } break;
2293             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2294                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2295                 try {
2296                     connection.shutdown();
2297                 } catch (RemoteException e) {
2298                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2299                 }
2300                 // Only a UiAutomation can set this flag and now that
2301                 // it is finished we make sure it is reset to its default.
2302                 mUserIsMonkey = false;
2303             } break;
2304             case APP_BOOST_DEACTIVATE_MSG: {
2305                 synchronized(ActivityManagerService.this) {
2306                     if (mIsBoosted) {
2307                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2308                             nativeMigrateFromBoost();
2309                             mIsBoosted = false;
2310                             mBoostStartTime = 0;
2311                         } else {
2312                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2313                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2314                         }
2315                     }
2316                 }
2317             } break;
2318             case IDLE_UIDS_MSG: {
2319                 idleUids();
2320             } break;
2321             case LOG_STACK_STATE: {
2322                 synchronized (ActivityManagerService.this) {
2323                     mStackSupervisor.logStackState();
2324                 }
2325             } break;
2326             case VR_MODE_CHANGE_MSG: {
2327                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2328                 if (vrService == null) {
2329                     break;
2330                 }
2331                 final ActivityRecord r = (ActivityRecord) msg.obj;
2332                 boolean vrMode;
2333                 ComponentName requestedPackage;
2334                 ComponentName callingPackage;
2335                 int userId;
2336                 synchronized (ActivityManagerService.this) {
2337                     vrMode = r.requestedVrComponent != null;
2338                     requestedPackage = r.requestedVrComponent;
2339                     userId = r.userId;
2340                     callingPackage = r.info.getComponentName();
2341                     if (mInVrMode != vrMode) {
2342                         mInVrMode = vrMode;
2343                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2344                         if (r.app != null) {
2345                             ProcessRecord proc = r.app;
2346                             if (proc.vrThreadTid > 0) {
2347                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2348                                     try {
2349                                         if (mInVrMode == true) {
2350                                             Process.setThreadScheduler(proc.vrThreadTid,
2351                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2352                                         } else {
2353                                             Process.setThreadScheduler(proc.vrThreadTid,
2354                                                 Process.SCHED_OTHER, 0);
2355                                         }
2356                                     } catch (IllegalArgumentException e) {
2357                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2358                                                 + " not exist:\n" + e);
2359                                     }
2360                                 }
2361                             }
2362                         }
2363                     }
2364                 }
2365                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2366             } case NOTIFY_VR_SLEEPING_MSG: {
2367                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2368             } break;
2369             }
2370         }
2371     };
2372
2373     static final int COLLECT_PSS_BG_MSG = 1;
2374
2375     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2376         @Override
2377         public void handleMessage(Message msg) {
2378             switch (msg.what) {
2379             case COLLECT_PSS_BG_MSG: {
2380                 long start = SystemClock.uptimeMillis();
2381                 MemInfoReader memInfo = null;
2382                 synchronized (ActivityManagerService.this) {
2383                     if (mFullPssPending) {
2384                         mFullPssPending = false;
2385                         memInfo = new MemInfoReader();
2386                     }
2387                 }
2388                 if (memInfo != null) {
2389                     updateCpuStatsNow();
2390                     long nativeTotalPss = 0;
2391                     final List<ProcessCpuTracker.Stats> stats;
2392                     synchronized (mProcessCpuTracker) {
2393                         stats = mProcessCpuTracker.getStats( (st)-> {
2394                             return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2395                         });
2396                     }
2397                     final int N = stats.size();
2398                     for (int j = 0; j < N; j++) {
2399                         synchronized (mPidsSelfLocked) {
2400                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2401                                 // This is one of our own processes; skip it.
2402                                 continue;
2403                             }
2404                         }
2405                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2406                     }
2407                     memInfo.readMemInfo();
2408                     synchronized (ActivityManagerService.this) {
2409                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2410                                 + (SystemClock.uptimeMillis()-start) + "ms");
2411                         final long cachedKb = memInfo.getCachedSizeKb();
2412                         final long freeKb = memInfo.getFreeSizeKb();
2413                         final long zramKb = memInfo.getZramTotalSizeKb();
2414                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2415                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2416                                 kernelKb*1024, nativeTotalPss*1024);
2417                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2418                                 nativeTotalPss);
2419                     }
2420                 }
2421
2422                 int num = 0;
2423                 long[] tmp = new long[2];
2424                 do {
2425                     ProcessRecord proc;
2426                     int procState;
2427                     int pid;
2428                     long lastPssTime;
2429                     synchronized (ActivityManagerService.this) {
2430                         if (mPendingPssProcesses.size() <= 0) {
2431                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2432                                     "Collected PSS of " + num + " processes in "
2433                                     + (SystemClock.uptimeMillis() - start) + "ms");
2434                             mPendingPssProcesses.clear();
2435                             return;
2436                         }
2437                         proc = mPendingPssProcesses.remove(0);
2438                         procState = proc.pssProcState;
2439                         lastPssTime = proc.lastPssTime;
2440                         if (proc.thread != null && procState == proc.setProcState
2441                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2442                                         < SystemClock.uptimeMillis()) {
2443                             pid = proc.pid;
2444                         } else {
2445                             proc = null;
2446                             pid = 0;
2447                         }
2448                     }
2449                     if (proc != null) {
2450                         long pss = Debug.getPss(pid, tmp, null);
2451                         synchronized (ActivityManagerService.this) {
2452                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2453                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2454                                 num++;
2455                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2456                                         SystemClock.uptimeMillis());
2457                             }
2458                         }
2459                     }
2460                 } while (true);
2461             }
2462             }
2463         }
2464     };
2465
2466     public void setSystemProcess() {
2467         try {
2468             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2469             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2470             ServiceManager.addService("meminfo", new MemBinder(this));
2471             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2472             ServiceManager.addService("dbinfo", new DbBinder(this));
2473             if (MONITOR_CPU_USAGE) {
2474                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2475             }
2476             ServiceManager.addService("permission", new PermissionController(this));
2477             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2478
2479             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2480                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2481             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2482
2483             synchronized (this) {
2484                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2485                 app.persistent = true;
2486                 app.pid = MY_PID;
2487                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2488                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2489                 synchronized (mPidsSelfLocked) {
2490                     mPidsSelfLocked.put(app.pid, app);
2491                 }
2492                 updateLruProcessLocked(app, false, null);
2493                 updateOomAdjLocked();
2494             }
2495         } catch (PackageManager.NameNotFoundException e) {
2496             throw new RuntimeException(
2497                     "Unable to find android system package", e);
2498         }
2499     }
2500
2501     public void setWindowManager(WindowManagerService wm) {
2502         mWindowManager = wm;
2503         mStackSupervisor.setWindowManager(wm);
2504         mActivityStarter.setWindowManager(wm);
2505     }
2506
2507     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2508         mUsageStatsService = usageStatsManager;
2509     }
2510
2511     public void startObservingNativeCrashes() {
2512         final NativeCrashListener ncl = new NativeCrashListener(this);
2513         ncl.start();
2514     }
2515
2516     public IAppOpsService getAppOpsService() {
2517         return mAppOpsService;
2518     }
2519
2520     static class MemBinder extends Binder {
2521         ActivityManagerService mActivityManagerService;
2522         MemBinder(ActivityManagerService activityManagerService) {
2523             mActivityManagerService = activityManagerService;
2524         }
2525
2526         @Override
2527         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2528             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2529                     != PackageManager.PERMISSION_GRANTED) {
2530                 pw.println("Permission Denial: can't dump meminfo from from pid="
2531                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2532                         + " without permission " + android.Manifest.permission.DUMP);
2533                 return;
2534             }
2535
2536             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2537         }
2538     }
2539
2540     static class GraphicsBinder extends Binder {
2541         ActivityManagerService mActivityManagerService;
2542         GraphicsBinder(ActivityManagerService activityManagerService) {
2543             mActivityManagerService = activityManagerService;
2544         }
2545
2546         @Override
2547         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2548             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2549                     != PackageManager.PERMISSION_GRANTED) {
2550                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2551                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2552                         + " without permission " + android.Manifest.permission.DUMP);
2553                 return;
2554             }
2555
2556             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2557         }
2558     }
2559
2560     static class DbBinder extends Binder {
2561         ActivityManagerService mActivityManagerService;
2562         DbBinder(ActivityManagerService activityManagerService) {
2563             mActivityManagerService = activityManagerService;
2564         }
2565
2566         @Override
2567         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2568             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2569                     != PackageManager.PERMISSION_GRANTED) {
2570                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2571                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2572                         + " without permission " + android.Manifest.permission.DUMP);
2573                 return;
2574             }
2575
2576             mActivityManagerService.dumpDbInfo(fd, pw, args);
2577         }
2578     }
2579
2580     static class CpuBinder extends Binder {
2581         ActivityManagerService mActivityManagerService;
2582         CpuBinder(ActivityManagerService activityManagerService) {
2583             mActivityManagerService = activityManagerService;
2584         }
2585
2586         @Override
2587         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2588             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2589                     != PackageManager.PERMISSION_GRANTED) {
2590                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2591                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2592                         + " without permission " + android.Manifest.permission.DUMP);
2593                 return;
2594             }
2595
2596             synchronized (mActivityManagerService.mProcessCpuTracker) {
2597                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2598                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2599                         SystemClock.uptimeMillis()));
2600             }
2601         }
2602     }
2603
2604     public static final class Lifecycle extends SystemService {
2605         private final ActivityManagerService mService;
2606
2607         public Lifecycle(Context context) {
2608             super(context);
2609             mService = new ActivityManagerService(context);
2610         }
2611
2612         @Override
2613         public void onStart() {
2614             mService.start();
2615         }
2616
2617         public ActivityManagerService getService() {
2618             return mService;
2619         }
2620     }
2621
2622     // Note: This method is invoked on the main thread but may need to attach various
2623     // handlers to other threads.  So take care to be explicit about the looper.
2624     public ActivityManagerService(Context systemContext) {
2625         mContext = systemContext;
2626         mFactoryTest = FactoryTest.getMode();
2627         mSystemThread = ActivityThread.currentActivityThread();
2628
2629         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2630
2631         mPermissionReviewRequired = mContext.getResources().getBoolean(
2632                 com.android.internal.R.bool.config_permissionReviewRequired);
2633
2634         mHandlerThread = new ServiceThread(TAG,
2635                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2636         mHandlerThread.start();
2637         mHandler = new MainHandler(mHandlerThread.getLooper());
2638         mUiHandler = new UiHandler();
2639
2640         /* static; one-time init here */
2641         if (sKillHandler == null) {
2642             sKillThread = new ServiceThread(TAG + ":kill",
2643                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2644             sKillThread.start();
2645             sKillHandler = new KillHandler(sKillThread.getLooper());
2646         }
2647
2648         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2649                 "foreground", BROADCAST_FG_TIMEOUT, false);
2650         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2651                 "background", BROADCAST_BG_TIMEOUT, true);
2652         mBroadcastQueues[0] = mFgBroadcastQueue;
2653         mBroadcastQueues[1] = mBgBroadcastQueue;
2654
2655         mServices = new ActiveServices(this);
2656         mProviderMap = new ProviderMap(this);
2657         mAppErrors = new AppErrors(mContext, this);
2658
2659         // TODO: Move creation of battery stats service outside of activity manager service.
2660         File dataDir = Environment.getDataDirectory();
2661         File systemDir = new File(dataDir, "system");
2662         systemDir.mkdirs();
2663         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2664         mBatteryStatsService.getActiveStatistics().readLocked();
2665         mBatteryStatsService.scheduleWriteToDisk();
2666         mOnBattery = DEBUG_POWER ? true
2667                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2668         mBatteryStatsService.getActiveStatistics().setCallback(this);
2669
2670         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2671
2672         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2673         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2674                 new IAppOpsCallback.Stub() {
2675                     @Override public void opChanged(int op, int uid, String packageName) {
2676                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2677                             if (mAppOpsService.checkOperation(op, uid, packageName)
2678                                     != AppOpsManager.MODE_ALLOWED) {
2679                                 runInBackgroundDisabled(uid);
2680                             }
2681                         }
2682                     }
2683                 });
2684
2685         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2686
2687         mUserController = new UserController(this);
2688
2689         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2690             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2691
2692         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2693             mUseFifoUiScheduling = true;
2694         }
2695
2696         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2697
2698         mConfiguration.setToDefaults();
2699         mConfiguration.setLocales(LocaleList.getDefault());
2700
2701         mConfigurationSeq = mConfiguration.seq = 1;
2702         mProcessCpuTracker.init();
2703
2704         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2705         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2706         mStackSupervisor = new ActivityStackSupervisor(this);
2707         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2708         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2709
2710         mProcessCpuThread = new Thread("CpuTracker") {
2711             @Override
2712             public void run() {
2713                 while (true) {
2714                     try {
2715                         try {
2716                             synchronized(this) {
2717                                 final long now = SystemClock.uptimeMillis();
2718                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2719                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2720                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2721                                 //        + ", write delay=" + nextWriteDelay);
2722                                 if (nextWriteDelay < nextCpuDelay) {
2723                                     nextCpuDelay = nextWriteDelay;
2724                                 }
2725                                 if (nextCpuDelay > 0) {
2726                                     mProcessCpuMutexFree.set(true);
2727                                     this.wait(nextCpuDelay);
2728                                 }
2729                             }
2730                         } catch (InterruptedException e) {
2731                         }
2732                         updateCpuStatsNow();
2733                     } catch (Exception e) {
2734                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2735                     }
2736                 }
2737             }
2738         };
2739
2740         Watchdog.getInstance().addMonitor(this);
2741         Watchdog.getInstance().addThread(mHandler);
2742     }
2743
2744     public void setSystemServiceManager(SystemServiceManager mgr) {
2745         mSystemServiceManager = mgr;
2746     }
2747
2748     public void setInstaller(Installer installer) {
2749         mInstaller = installer;
2750     }
2751
2752     private void start() {
2753         Process.removeAllProcessGroups();
2754         mProcessCpuThread.start();
2755
2756         mBatteryStatsService.publish(mContext);
2757         mAppOpsService.publish(mContext);
2758         Slog.d("AppOps", "AppOpsService published");
2759         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2760     }
2761
2762     void onUserStoppedLocked(int userId) {
2763         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2764     }
2765
2766     public void initPowerManagement() {
2767         mStackSupervisor.initPowerManagement();
2768         mBatteryStatsService.initPowerManagement();
2769         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2770         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2771         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2772         mVoiceWakeLock.setReferenceCounted(false);
2773     }
2774
2775     @Override
2776     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2777             throws RemoteException {
2778         if (code == SYSPROPS_TRANSACTION) {
2779             // We need to tell all apps about the system property change.
2780             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2781             synchronized(this) {
2782                 final int NP = mProcessNames.getMap().size();
2783                 for (int ip=0; ip<NP; ip++) {
2784                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2785                     final int NA = apps.size();
2786                     for (int ia=0; ia<NA; ia++) {
2787                         ProcessRecord app = apps.valueAt(ia);
2788                         if (app.thread != null) {
2789                             procs.add(app.thread.asBinder());
2790                         }
2791                     }
2792                 }
2793             }
2794
2795             int N = procs.size();
2796             for (int i=0; i<N; i++) {
2797                 Parcel data2 = Parcel.obtain();
2798                 try {
2799                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2800                 } catch (RemoteException e) {
2801                 }
2802                 data2.recycle();
2803             }
2804         }
2805         try {
2806             return super.onTransact(code, data, reply, flags);
2807         } catch (RuntimeException e) {
2808             // The activity manager only throws security exceptions, so let's
2809             // log all others.
2810             if (!(e instanceof SecurityException)) {
2811                 Slog.wtf(TAG, "Activity Manager Crash", e);
2812             }
2813             throw e;
2814         }
2815     }
2816
2817     void updateCpuStats() {
2818         final long now = SystemClock.uptimeMillis();
2819         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2820             return;
2821         }
2822         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2823             synchronized (mProcessCpuThread) {
2824                 mProcessCpuThread.notify();
2825             }
2826         }
2827     }
2828
2829     void updateCpuStatsNow() {
2830         synchronized (mProcessCpuTracker) {
2831             mProcessCpuMutexFree.set(false);
2832             final long now = SystemClock.uptimeMillis();
2833             boolean haveNewCpuStats = false;
2834
2835             if (MONITOR_CPU_USAGE &&
2836                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2837                 mLastCpuTime.set(now);
2838                 mProcessCpuTracker.update();
2839                 if (mProcessCpuTracker.hasGoodLastStats()) {
2840                     haveNewCpuStats = true;
2841                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2842                     //Slog.i(TAG, "Total CPU usage: "
2843                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2844
2845                     // Slog the cpu usage if the property is set.
2846                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2847                         int user = mProcessCpuTracker.getLastUserTime();
2848                         int system = mProcessCpuTracker.getLastSystemTime();
2849                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2850                         int irq = mProcessCpuTracker.getLastIrqTime();
2851                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2852                         int idle = mProcessCpuTracker.getLastIdleTime();
2853
2854                         int total = user + system + iowait + irq + softIrq + idle;
2855                         if (total == 0) total = 1;
2856
2857                         EventLog.writeEvent(EventLogTags.CPU,
2858                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2859                                 (user * 100) / total,
2860                                 (system * 100) / total,
2861                                 (iowait * 100) / total,
2862                                 (irq * 100) / total,
2863                                 (softIrq * 100) / total);
2864                     }
2865                 }
2866             }
2867
2868             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2869             synchronized(bstats) {
2870                 synchronized(mPidsSelfLocked) {
2871                     if (haveNewCpuStats) {
2872                         if (bstats.startAddingCpuLocked()) {
2873                             int totalUTime = 0;
2874                             int totalSTime = 0;
2875                             final int N = mProcessCpuTracker.countStats();
2876                             for (int i=0; i<N; i++) {
2877                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2878                                 if (!st.working) {
2879                                     continue;
2880                                 }
2881                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2882                                 totalUTime += st.rel_utime;
2883                                 totalSTime += st.rel_stime;
2884                                 if (pr != null) {
2885                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2886                                     if (ps == null || !ps.isActive()) {
2887                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2888                                                 pr.info.uid, pr.processName);
2889                                     }
2890                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2891                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2892                                 } else {
2893                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2894                                     if (ps == null || !ps.isActive()) {
2895                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2896                                                 bstats.mapUid(st.uid), st.name);
2897                                     }
2898                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2899                                 }
2900                             }
2901                             final int userTime = mProcessCpuTracker.getLastUserTime();
2902                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2903                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2904                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2905                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2906                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2907                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2908                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2909                         }
2910                     }
2911                 }
2912
2913                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2914                     mLastWriteTime = now;
2915                     mBatteryStatsService.scheduleWriteToDisk();
2916                 }
2917             }
2918         }
2919     }
2920
2921     @Override
2922     public void batteryNeedsCpuUpdate() {
2923         updateCpuStatsNow();
2924     }
2925
2926     @Override
2927     public void batteryPowerChanged(boolean onBattery) {
2928         // When plugging in, update the CPU stats first before changing
2929         // the plug state.
2930         updateCpuStatsNow();
2931         synchronized (this) {
2932             synchronized(mPidsSelfLocked) {
2933                 mOnBattery = DEBUG_POWER ? true : onBattery;
2934             }
2935         }
2936     }
2937
2938     @Override
2939     public void batterySendBroadcast(Intent intent) {
2940         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2941                 AppOpsManager.OP_NONE, null, false, false,
2942                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2943     }
2944
2945     /**
2946      * Initialize the application bind args. These are passed to each
2947      * process when the bindApplication() IPC is sent to the process. They're
2948      * lazily setup to make sure the services are running when they're asked for.
2949      */
2950     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2951         // Isolated processes won't get this optimization, so that we don't
2952         // violate the rules about which services they have access to.
2953         if (isolated) {
2954             if (mIsolatedAppBindArgs == null) {
2955                 mIsolatedAppBindArgs = new HashMap<>();
2956                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2957             }
2958             return mIsolatedAppBindArgs;
2959         }
2960
2961         if (mAppBindArgs == null) {
2962             mAppBindArgs = new HashMap<>();
2963
2964             // Setup the application init args
2965             mAppBindArgs.put("package", ServiceManager.getService("package"));
2966             mAppBindArgs.put("window", ServiceManager.getService("window"));
2967             mAppBindArgs.put(Context.ALARM_SERVICE,
2968                     ServiceManager.getService(Context.ALARM_SERVICE));
2969         }
2970         return mAppBindArgs;
2971     }
2972
2973     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2974         if (r == null || mFocusedActivity == r) {
2975             return false;
2976         }
2977
2978         if (!r.isFocusable()) {
2979             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2980             return false;
2981         }
2982
2983         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2984
2985         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2986         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2987                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2988         mDoingSetFocusedActivity = true;
2989
2990         final ActivityRecord last = mFocusedActivity;
2991         mFocusedActivity = r;
2992         if (r.task.isApplicationTask()) {
2993             if (mCurAppTimeTracker != r.appTimeTracker) {
2994                 // We are switching app tracking.  Complete the current one.
2995                 if (mCurAppTimeTracker != null) {
2996                     mCurAppTimeTracker.stop();
2997                     mHandler.obtainMessage(
2998                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2999                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3000                     mCurAppTimeTracker = null;
3001                 }
3002                 if (r.appTimeTracker != null) {
3003                     mCurAppTimeTracker = r.appTimeTracker;
3004                     startTimeTrackingFocusedActivityLocked();
3005                 }
3006             } else {
3007                 startTimeTrackingFocusedActivityLocked();
3008             }
3009         } else {
3010             r.appTimeTracker = null;
3011         }
3012         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3013         // TODO: Probably not, because we don't want to resume voice on switching
3014         // back to this activity
3015         if (r.task.voiceInteractor != null) {
3016             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3017         } else {
3018             finishRunningVoiceLocked();
3019             IVoiceInteractionSession session;
3020             if (last != null && ((session = last.task.voiceSession) != null
3021                     || (session = last.voiceSession) != null)) {
3022                 // We had been in a voice interaction session, but now focused has
3023                 // move to something different.  Just finish the session, we can't
3024                 // return to it and retain the proper state and synchronization with
3025                 // the voice interaction service.
3026                 finishVoiceTask(session);
3027             }
3028         }
3029         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3030             mWindowManager.setFocusedApp(r.appToken, true);
3031         }
3032         applyUpdateLockStateLocked(r);
3033         applyUpdateVrModeLocked(r);
3034         if (mFocusedActivity.userId != mLastFocusedUserId) {
3035             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3036             mHandler.obtainMessage(
3037                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3038             mLastFocusedUserId = mFocusedActivity.userId;
3039         }
3040
3041         // Log a warning if the focused app is changed during the process. This could
3042         // indicate a problem of the focus setting logic!
3043         if (mFocusedActivity != r) Slog.w(TAG,
3044                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3045         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3046
3047         EventLogTags.writeAmFocusedActivity(
3048                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3049                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3050                 reason);
3051         return true;
3052     }
3053
3054     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3055         if (mFocusedActivity != goingAway) {
3056             return;
3057         }
3058
3059         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3060         if (focusedStack != null) {
3061             final ActivityRecord top = focusedStack.topActivity();
3062             if (top != null && top.userId != mLastFocusedUserId) {
3063                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3064                 mHandler.sendMessage(
3065                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3066                 mLastFocusedUserId = top.userId;
3067             }
3068         }
3069
3070         // Try to move focus to another activity if possible.
3071         if (setFocusedActivityLocked(
3072                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3073             return;
3074         }
3075
3076         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3077                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3078         mFocusedActivity = null;
3079         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3080     }
3081
3082     @Override
3083     public void setFocusedStack(int stackId) {
3084         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3085         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3086         final long callingId = Binder.clearCallingIdentity();
3087         try {
3088             synchronized (this) {
3089                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3090                 if (stack == null) {
3091                     return;
3092                 }
3093                 final ActivityRecord r = stack.topRunningActivityLocked();
3094                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3095                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3096                 }
3097             }
3098         } finally {
3099             Binder.restoreCallingIdentity(callingId);
3100         }
3101     }
3102
3103     @Override
3104     public void setFocusedTask(int taskId) {
3105         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3106         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3107         final long callingId = Binder.clearCallingIdentity();
3108         try {
3109             synchronized (this) {
3110                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3111                 if (task == null) {
3112                     return;
3113                 }
3114                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3115                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3116                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3117                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3118                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3119                                 "setFocusedTask", ANIMATE);
3120                     }
3121                     return;
3122                 }
3123                 final ActivityRecord r = task.topRunningActivityLocked();
3124                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3125                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3126                 }
3127             }
3128         } finally {
3129             Binder.restoreCallingIdentity(callingId);
3130         }
3131     }
3132
3133     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3134     @Override
3135     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3136         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3137         synchronized (this) {
3138             if (listener != null) {
3139                 mTaskStackListeners.register(listener);
3140             }
3141         }
3142     }
3143
3144     @Override
3145     public void notifyActivityDrawn(IBinder token) {
3146         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3147         synchronized (this) {
3148             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3149             if (r != null) {
3150                 r.task.stack.notifyActivityDrawnLocked(r);
3151             }
3152         }
3153     }
3154
3155     final void applyUpdateLockStateLocked(ActivityRecord r) {
3156         // Modifications to the UpdateLock state are done on our handler, outside
3157         // the activity manager's locks.  The new state is determined based on the
3158         // state *now* of the relevant activity record.  The object is passed to
3159         // the handler solely for logging detail, not to be consulted/modified.
3160         final boolean nextState = r != null && r.immersive;
3161         mHandler.sendMessage(
3162                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3163     }
3164
3165     final void applyUpdateVrModeLocked(ActivityRecord r) {
3166         mHandler.sendMessage(
3167                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3168     }
3169
3170     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3171         mHandler.sendMessage(
3172                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3173     }
3174
3175     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3176         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3177         if (vrService == null) {
3178             return;
3179         }
3180         vrService.onSleepStateChanged(isSleeping);
3181     }
3182
3183     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184         Message msg = Message.obtain();
3185         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186         msg.obj = r.task.askedCompatMode ? null : r;
3187         mUiHandler.sendMessage(msg);
3188     }
3189
3190     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193             final Message msg = Message.obtain();
3194             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3195             msg.obj = r;
3196             mUiHandler.sendMessage(msg);
3197         }
3198     }
3199
3200     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201             String what, Object obj, ProcessRecord srcApp) {
3202         app.lastActivityTime = now;
3203
3204         if (app.activities.size() > 0) {
3205             // Don't want to touch dependent processes that are hosting activities.
3206             return index;
3207         }
3208
3209         int lrui = mLruProcesses.lastIndexOf(app);
3210         if (lrui < 0) {
3211             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212                     + what + " " + obj + " from " + srcApp);
3213             return index;
3214         }
3215
3216         if (lrui >= index) {
3217             // Don't want to cause this to move dependent processes *back* in the
3218             // list as if they were less frequently used.
3219             return index;
3220         }
3221
3222         if (lrui >= mLruProcessActivityStart) {
3223             // Don't want to touch dependent processes that are hosting activities.
3224             return index;
3225         }
3226
3227         mLruProcesses.remove(lrui);
3228         if (index > 0) {
3229             index--;
3230         }
3231         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232                 + " in LRU list: " + app);
3233         mLruProcesses.add(index, app);
3234         return index;
3235     }
3236
3237     static void killProcessGroup(int uid, int pid) {
3238         if (sKillHandler != null) {
3239             sKillHandler.sendMessage(
3240                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3241         } else {
3242             Slog.w(TAG, "Asked to kill process group before system bringup!");
3243             Process.killProcessGroup(uid, pid);
3244         }
3245     }
3246
3247     final void removeLruProcessLocked(ProcessRecord app) {
3248         int lrui = mLruProcesses.lastIndexOf(app);
3249         if (lrui >= 0) {
3250             if (!app.killed) {
3251                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252                 Process.killProcessQuiet(app.pid);
3253                 killProcessGroup(app.uid, app.pid);
3254             }
3255             if (lrui <= mLruProcessActivityStart) {
3256                 mLruProcessActivityStart--;
3257             }
3258             if (lrui <= mLruProcessServiceStart) {
3259                 mLruProcessServiceStart--;
3260             }
3261             mLruProcesses.remove(lrui);
3262         }
3263     }
3264
3265     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266             ProcessRecord client) {
3267         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268                 || app.treatLikeActivity;
3269         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270         if (!activityChange && hasActivity) {
3271             // The process has activities, so we are only allowing activity-based adjustments
3272             // to move it.  It should be kept in the front of the list with other
3273             // processes that have activities, and we don't want those to change their
3274             // order except due to activity operations.
3275             return;
3276         }
3277
3278         mLruSeq++;
3279         final long now = SystemClock.uptimeMillis();
3280         app.lastActivityTime = now;
3281
3282         // First a quick reject: if the app is already at the position we will
3283         // put it, then there is nothing to do.
3284         if (hasActivity) {
3285             final int N = mLruProcesses.size();
3286             if (N > 0 && mLruProcesses.get(N-1) == app) {
3287                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3288                 return;
3289             }
3290         } else {
3291             if (mLruProcessServiceStart > 0
3292                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3294                 return;
3295             }
3296         }
3297
3298         int lrui = mLruProcesses.lastIndexOf(app);
3299
3300         if (app.persistent && lrui >= 0) {
3301             // We don't care about the position of persistent processes, as long as
3302             // they are in the list.
3303             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3304             return;
3305         }
3306
3307         /* In progress: compute new position first, so we can avoid doing work
3308            if the process is not actually going to move.  Not yet working.
3309         int addIndex;
3310         int nextIndex;
3311         boolean inActivity = false, inService = false;
3312         if (hasActivity) {
3313             // Process has activities, put it at the very tipsy-top.
3314             addIndex = mLruProcesses.size();
3315             nextIndex = mLruProcessServiceStart;
3316             inActivity = true;
3317         } else if (hasService) {
3318             // Process has services, put it at the top of the service list.
3319             addIndex = mLruProcessActivityStart;
3320             nextIndex = mLruProcessServiceStart;
3321             inActivity = true;
3322             inService = true;
3323         } else  {
3324             // Process not otherwise of interest, it goes to the top of the non-service area.
3325             addIndex = mLruProcessServiceStart;
3326             if (client != null) {
3327                 int clientIndex = mLruProcesses.lastIndexOf(client);
3328                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3329                         + app);
3330                 if (clientIndex >= 0 && addIndex > clientIndex) {
3331                     addIndex = clientIndex;
3332                 }
3333             }
3334             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3335         }
3336
3337         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338                 + mLruProcessActivityStart + "): " + app);
3339         */
3340
3341         if (lrui >= 0) {
3342             if (lrui < mLruProcessActivityStart) {
3343                 mLruProcessActivityStart--;
3344             }
3345             if (lrui < mLruProcessServiceStart) {
3346                 mLruProcessServiceStart--;
3347             }
3348             /*
3349             if (addIndex > lrui) {
3350                 addIndex--;
3351             }
3352             if (nextIndex > lrui) {
3353                 nextIndex--;
3354             }
3355             */
3356             mLruProcesses.remove(lrui);
3357         }
3358
3359         /*
3360         mLruProcesses.add(addIndex, app);
3361         if (inActivity) {
3362             mLruProcessActivityStart++;
3363         }
3364         if (inService) {
3365             mLruProcessActivityStart++;
3366         }
3367         */
3368
3369         int nextIndex;
3370         if (hasActivity) {
3371             final int N = mLruProcesses.size();
3372             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373                 // Process doesn't have activities, but has clients with
3374                 // activities...  move it up, but one below the top (the top
3375                 // should always have a real activity).
3376                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377                         "Adding to second-top of LRU activity list: " + app);
3378                 mLruProcesses.add(N - 1, app);
3379                 // To keep it from spamming the LRU list (by making a bunch of clients),
3380                 // we will push down any other entries owned by the app.
3381                 final int uid = app.info.uid;
3382                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383                     ProcessRecord subProc = mLruProcesses.get(i);
3384                     if (subProc.info.uid == uid) {
3385                         // We want to push this one down the list.  If the process after
3386                         // it is for the same uid, however, don't do so, because we don't
3387                         // want them internally to be re-ordered.
3388                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3389                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3390                                     "Pushing uid " + uid + " swapping at " + i + ": "
3391                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392                             ProcessRecord tmp = mLruProcesses.get(i);
3393                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394                             mLruProcesses.set(i - 1, tmp);
3395                             i--;
3396                         }
3397                     } else {
3398                         // A gap, we can stop here.
3399                         break;
3400                     }
3401                 }
3402             } else {
3403                 // Process has activities, put it at the very tipsy-top.
3404                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405                 mLruProcesses.add(app);
3406             }
3407             nextIndex = mLruProcessServiceStart;
3408         } else if (hasService) {
3409             // Process has services, put it at the top of the service list.
3410             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411             mLruProcesses.add(mLruProcessActivityStart, app);
3412             nextIndex = mLruProcessServiceStart;
3413             mLruProcessActivityStart++;
3414         } else  {
3415             // Process not otherwise of interest, it goes to the top of the non-service area.
3416             int index = mLruProcessServiceStart;
3417             if (client != null) {
3418                 // If there is a client, don't allow the process to be moved up higher
3419                 // in the list than that client.
3420                 int clientIndex = mLruProcesses.lastIndexOf(client);
3421                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422                         + " when updating " + app);
3423                 if (clientIndex <= lrui) {
3424                     // Don't allow the client index restriction to push it down farther in the
3425                     // list than it already is.
3426                     clientIndex = lrui;
3427                 }
3428                 if (clientIndex >= 0 && index > clientIndex) {
3429                     index = clientIndex;
3430                 }
3431             }
3432             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433             mLruProcesses.add(index, app);
3434             nextIndex = index-1;
3435             mLruProcessActivityStart++;
3436             mLruProcessServiceStart++;
3437         }
3438
3439         // If the app is currently using a content provider or service,
3440         // bump those processes as well.
3441         for (int j=app.connections.size()-1; j>=0; j--) {
3442             ConnectionRecord cr = app.connections.valueAt(j);
3443             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444                     && cr.binding.service.app != null
3445                     && cr.binding.service.app.lruSeq != mLruSeq
3446                     && !cr.binding.service.app.persistent) {
3447                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448                         "service connection", cr, app);
3449             }
3450         }
3451         for (int j=app.conProviders.size()-1; j>=0; j--) {
3452             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455                         "provider reference", cpr, app);
3456             }
3457         }
3458     }
3459
3460     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461         if (uid == Process.SYSTEM_UID) {
3462             // The system gets to run in any process.  If there are multiple
3463             // processes with the same uid, just pick the first (this
3464             // should never happen).
3465             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466             if (procs == null) return null;
3467             final int procCount = procs.size();
3468             for (int i = 0; i < procCount; i++) {
3469                 final int procUid = procs.keyAt(i);
3470                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471                     // Don't use an app process or different user process for system component.
3472                     continue;
3473                 }
3474                 return procs.valueAt(i);
3475             }
3476         }
3477         ProcessRecord proc = mProcessNames.get(processName, uid);
3478         if (false && proc != null && !keepIfLarge
3479                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480                 && proc.lastCachedPss >= 4000) {
3481             // Turn this condition on to cause killing to happen regularly, for testing.
3482             if (proc.baseProcessTracker != null) {
3483                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3484             }
3485             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486         } else if (proc != null && !keepIfLarge
3487                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491                 if (proc.baseProcessTracker != null) {
3492                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3493                 }
3494                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3495             }
3496         }
3497         return proc;
3498     }
3499
3500     void notifyPackageUse(String packageName, int reason) {
3501         IPackageManager pm = AppGlobals.getPackageManager();
3502         try {
3503             pm.notifyPackageUse(packageName, reason);
3504         } catch (RemoteException e) {
3505         }
3506     }
3507
3508     boolean isNextTransitionForward() {
3509         int transit = mWindowManager.getPendingAppTransition();
3510         return transit == TRANSIT_ACTIVITY_OPEN
3511                 || transit == TRANSIT_TASK_OPEN
3512                 || transit == TRANSIT_TASK_TO_FRONT;
3513     }
3514
3515     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516             String processName, String abiOverride, int uid, Runnable crashHandler) {
3517         synchronized(this) {
3518             ApplicationInfo info = new ApplicationInfo();
3519             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520             // For isolated processes, the former contains the parent's uid and the latter the
3521             // actual uid of the isolated process.
3522             // In the special case introduced by this method (which is, starting an isolated
3523             // process directly from the SystemServer without an actual parent app process) the
3524             // closest thing to a parent's uid is SYSTEM_UID.
3525             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526             // the |isolated| logic in the ProcessRecord constructor.
3527             info.uid = Process.SYSTEM_UID;
3528             info.processName = processName;
3529             info.className = entryPoint;
3530             info.packageName = "android";
3531             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3533                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3535                     crashHandler);
3536             return proc != null ? proc.pid : 0;
3537         }
3538     }
3539
3540     final ProcessRecord startProcessLocked(String processName,
3541             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543             boolean isolated, boolean keepIfLarge) {
3544         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547                 null /* crashHandler */);
3548     }
3549
3550     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554         long startTime = SystemClock.elapsedRealtime();
3555         ProcessRecord app;
3556         if (!isolated) {
3557             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558             checkTime(startTime, "startProcess: after getProcessRecord");
3559
3560             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561                 // If we are in the background, then check to see if this process
3562                 // is bad.  If so, we will just silently fail.
3563                 if (mAppErrors.isBadProcessLocked(info)) {
3564                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565                             + "/" + info.processName);
3566                     return null;
3567                 }
3568             } else {
3569                 // When the user is explicitly starting a process, then clear its
3570                 // crash count so that we won't make it bad until they see at
3571                 // least one crash dialog again, and make the process good again
3572                 // if it had been bad.
3573                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574                         + "/" + info.processName);
3575                 mAppErrors.resetProcessCrashTimeLocked(info);
3576                 if (mAppErrors.isBadProcessLocked(info)) {
3577                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578                             UserHandle.getUserId(info.uid), info.uid,
3579                             info.processName);
3580                     mAppErrors.clearBadProcessLocked(info);
3581                     if (app != null) {
3582                         app.bad = false;
3583                     }
3584                 }
3585             }
3586         } else {
3587             // If this is an isolated process, it can't re-use an existing process.
3588             app = null;
3589         }
3590
3591         // app launch boost for big.little configurations
3592         // use cpusets to migrate freshly launched tasks to big cores
3593         nativeMigrateToBoost();
3594         mIsBoosted = true;
3595         mBoostStartTime = SystemClock.uptimeMillis();
3596         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3598
3599         // We don't have to do anything more if:
3600         // (1) There is an existing application record; and
3601         // (2) The caller doesn't think it is dead, OR there is no thread
3602         //     object attached to it so we know it couldn't have crashed; and
3603         // (3) There is a pid assigned to it, so it is either starting or
3604         //     already running.
3605         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607                 + " thread=" + (app != null ? app.thread : null)
3608                 + " pid=" + (app != null ? app.pid : -1));
3609         if (app != null && app.pid > 0) {
3610             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611                 // We already have the app running, or are waiting for it to
3612                 // come up (we have a pid but not yet its thread), so keep it.
3613                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614                 // If this is a new package in the process, add the package to the list
3615                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616                 checkTime(startTime, "startProcess: done, added package to proc");
3617                 return app;
3618             }
3619
3620             // An application record is attached to a previous process,
3621             // clean it up now.
3622             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623             checkTime(startTime, "startProcess: bad proc running, killing");
3624             killProcessGroup(app.uid, app.pid);
3625             handleAppDiedLocked(app, true, true);
3626             checkTime(startTime, "startProcess: done killing old proc");
3627         }
3628
3629         String hostingNameStr = hostingName != null
3630                 ? hostingName.flattenToShortString() : null;
3631
3632         if (app == null) {
3633             checkTime(startTime, "startProcess: creating new process record");
3634             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3635             if (app == null) {
3636                 Slog.w(TAG, "Failed making new process record for "
3637                         + processName + "/" + info.uid + " isolated=" + isolated);
3638                 return null;
3639             }
3640             app.crashHandler = crashHandler;
3641             checkTime(startTime, "startProcess: done creating new process record");
3642         } else {
3643             // If this is a new package in the process, add the package to the list
3644             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645             checkTime(startTime, "startProcess: added package to existing proc");
3646         }
3647
3648         // If the system is not ready yet, then hold off on starting this
3649         // process until it is.
3650         if (!mProcessesReady
3651                 && !isAllowedWhileBooting(info)
3652                 && !allowWhileBooting) {
3653             if (!mProcessesOnHold.contains(app)) {
3654                 mProcessesOnHold.add(app);
3655             }
3656             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657                     "System not ready, putting on hold: " + app);
3658             checkTime(startTime, "startProcess: returning with proc on hold");
3659             return app;
3660         }
3661
3662         checkTime(startTime, "startProcess: stepping in to startProcess");
3663         startProcessLocked(
3664                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665         checkTime(startTime, "startProcess: done starting proc!");
3666         return (app.pid != 0) ? app : null;
3667     }
3668
3669     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3671     }
3672
3673     private final void startProcessLocked(ProcessRecord app,
3674             String hostingType, String hostingNameStr) {
3675         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676                 null /* entryPoint */, null /* entryPointArgs */);
3677     }
3678
3679     private final void startProcessLocked(ProcessRecord app, String hostingType,
3680             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681         long startTime = SystemClock.elapsedRealtime();
3682         if (app.pid > 0 && app.pid != MY_PID) {
3683             checkTime(startTime, "startProcess: removing from pids map");
3684             synchronized (mPidsSelfLocked) {
3685                 mPidsSelfLocked.remove(app.pid);
3686                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3687             }
3688             checkTime(startTime, "startProcess: done removing from pids map");
3689             app.setPid(0);
3690         }
3691
3692         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693                 "startProcessLocked removing on hold: " + app);
3694         mProcessesOnHold.remove(app);
3695
3696         checkTime(startTime, "startProcess: starting to update cpu stats");
3697         updateCpuStats();
3698         checkTime(startTime, "startProcess: done updating cpu stats");
3699
3700         try {
3701             try {
3702                 final int userId = UserHandle.getUserId(app.uid);
3703                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704             } catch (RemoteException e) {
3705                 throw e.rethrowAsRuntimeException();
3706             }
3707
3708             int uid = app.uid;
3709             int[] gids = null;
3710             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711             if (!app.isolated) {
3712                 int[] permGids = null;
3713                 try {
3714                     checkTime(startTime, "startProcess: getting gids from package manager");
3715                     final IPackageManager pm = AppGlobals.getPackageManager();
3716                     permGids = pm.getPackageGids(app.info.packageName,
3717                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3719                             MountServiceInternal.class);
3720                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721                             app.info.packageName);
3722                 } catch (RemoteException e) {
3723                     throw e.rethrowAsRuntimeException();
3724                 }
3725
3726                 /*
3727                  * Add shared application and profile GIDs so applications can share some
3728                  * resources like shared libraries and access user-wide resources
3729                  */
3730                 if (ArrayUtils.isEmpty(permGids)) {
3731                     gids = new int[2];
3732                 } else {
3733                     gids = new int[permGids.length + 2];
3734                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3735                 }
3736                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3738             }
3739             checkTime(startTime, "startProcess: building args");
3740             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742                         && mTopComponent != null
3743                         && app.processName.equals(mTopComponent.getPackageName())) {
3744                     uid = 0;
3745                 }
3746                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3748                     uid = 0;
3749                 }
3750             }
3751             int debugFlags = 0;
3752             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754                 // Also turn on CheckJNI for debuggable apps. It's quite
3755                 // awkward to turn on otherwise.
3756                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3757             }
3758             // Run the app in safe mode if its manifest requests so or the
3759             // system is booted in safe mode.
3760             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761                 mSafeMode == true) {
3762                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3763             }
3764             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3766             }
3767             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768             if ("true".equals(genDebugInfoProperty)) {
3769                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3770             }
3771             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3773             }
3774             if ("1".equals(SystemProperties.get("debug.assert"))) {
3775                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3776             }
3777             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778                 // Enable all debug flags required by the native debugger.
3779                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3780                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3782                 mNativeDebuggingApp = null;
3783             }
3784
3785             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786             if (requiredAbi == null) {
3787                 requiredAbi = Build.SUPPORTED_ABIS[0];
3788             }
3789
3790             String instructionSet = null;
3791             if (app.info.primaryCpuAbi != null) {
3792                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3793             }
3794
3795             app.gids = gids;
3796             app.requiredAbi = requiredAbi;
3797             app.instructionSet = instructionSet;
3798
3799             // Start the process.  It will either succeed and return a result containing
3800             // the PID of the new process, or else throw a RuntimeException.
3801             boolean isActivityProcess = (entryPoint == null);
3802             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3804                     app.processName);
3805             checkTime(startTime, "startProcess: asking zygote to start proc");
3806             Process.ProcessStartResult startResult = Process.start(entryPoint,
3807                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3808                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809                     app.info.dataDir, entryPointArgs);
3810             checkTime(startTime, "startProcess: returned from zygote!");
3811             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3812
3813             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814             checkTime(startTime, "startProcess: done updating battery stats");
3815
3816             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817                     UserHandle.getUserId(uid), startResult.pid, uid,
3818                     app.processName, hostingType,
3819                     hostingNameStr != null ? hostingNameStr : "");
3820
3821             try {
3822                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3824             } catch (RemoteException ex) {
3825                 // Ignore
3826             }
3827
3828             if (app.persistent) {
3829                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3830             }
3831
3832             checkTime(startTime, "startProcess: building log message");
3833             StringBuilder buf = mStringBuilder;
3834             buf.setLength(0);
3835             buf.append("Start proc ");
3836             buf.append(startResult.pid);
3837             buf.append(':');
3838             buf.append(app.processName);
3839             buf.append('/');
3840             UserHandle.formatUid(buf, uid);
3841             if (!isActivityProcess) {
3842                 buf.append(" [");
3843                 buf.append(entryPoint);
3844                 buf.append("]");
3845             }
3846             buf.append(" for ");
3847             buf.append(hostingType);
3848             if (hostingNameStr != null) {
3849                 buf.append(" ");
3850                 buf.append(hostingNameStr);
3851             }
3852             Slog.i(TAG, buf.toString());
3853             app.setPid(startResult.pid);
3854             app.usingWrapper = startResult.usingWrapper;
3855             app.removed = false;
3856             app.killed = false;
3857             app.killedByAm = false;
3858             checkTime(startTime, "startProcess: starting to update pids map");
3859             ProcessRecord oldApp;
3860             synchronized (mPidsSelfLocked) {
3861                 oldApp = mPidsSelfLocked.get(startResult.pid);
3862             }
3863             // If there is already an app occupying that pid that hasn't been cleaned up
3864             if (oldApp != null && !app.isolated) {
3865                 // Clean up anything relating to this pid first
3866                 Slog.w(TAG, "Reusing pid " + startResult.pid
3867                         + " while app is still mapped to it");
3868                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869                         true /*replacingPid*/);
3870             }
3871             synchronized (mPidsSelfLocked) {
3872                 this.mPidsSelfLocked.put(startResult.pid, app);
3873                 if (isActivityProcess) {
3874                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3875                     msg.obj = app;
3876                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3878                 }
3879             }
3880             checkTime(startTime, "startProcess: done updating pids map");
3881         } catch (RuntimeException e) {
3882             Slog.e(TAG, "Failure starting process " + app.processName, e);
3883
3884             // Something went very wrong while trying to start this process; one
3885             // common case is when the package is frozen due to an active
3886             // upgrade. To recover, clean up any active bookkeeping related to
3887             // starting this process. (We already invoked this method once when
3888             // the package was initially frozen through KILL_APPLICATION_MSG, so
3889             // it doesn't hurt to use it again.)
3890             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3892         }
3893     }
3894
3895     void updateUsageStats(ActivityRecord component, boolean resumed) {
3896         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897                 "updateUsageStats: comp=" + component + "res=" + resumed);
3898         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3899         if (resumed) {
3900             if (mUsageStatsService != null) {
3901                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3903             }
3904             synchronized (stats) {
3905                 stats.noteActivityResumedLocked(component.app.uid);
3906             }
3907         } else {
3908             if (mUsageStatsService != null) {
3909                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3911             }
3912             synchronized (stats) {
3913                 stats.noteActivityPausedLocked(component.app.uid);
3914             }
3915         }
3916     }
3917
3918     Intent getHomeIntent() {
3919         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920         intent.setComponent(mTopComponent);
3921         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923             intent.addCategory(Intent.CATEGORY_HOME);
3924         }
3925         return intent;
3926     }
3927
3928     boolean startHomeActivityLocked(int userId, String reason) {
3929         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930                 && mTopAction == null) {
3931             // We are running in factory test mode, but unable to find
3932             // the factory test app, so just sit around displaying the
3933             // error message and don't try to start anything.
3934             return false;
3935         }
3936         Intent intent = getHomeIntent();
3937         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938         if (aInfo != null) {
3939             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940             // Don't do this if the home app is currently being
3941             // instrumented.
3942             aInfo = new ActivityInfo(aInfo);
3943             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945                     aInfo.applicationInfo.uid, true);
3946             if (app == null || app.instrumentationClass == null) {
3947                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3949             }
3950         } else {
3951             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3952         }
3953
3954         return true;
3955     }
3956
3957     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958         ActivityInfo ai = null;
3959         ComponentName comp = intent.getComponent();
3960         try {
3961             if (comp != null) {
3962                 // Factory test.
3963                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3964             } else {
3965                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3966                         intent,
3967                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3968                         flags, userId);
3969
3970                 if (info != null) {
3971                     ai = info.activityInfo;
3972                 }
3973             }
3974         } catch (RemoteException e) {
3975             // ignore
3976         }
3977
3978         return ai;
3979     }
3980
3981     /**
3982      * Starts the "new version setup screen" if appropriate.
3983      */
3984     void startSetupActivityLocked() {
3985         // Only do this once per boot.
3986         if (mCheckedForSetup) {
3987             return;
3988         }
3989
3990         // We will show this screen if the current one is a different
3991         // version than the last one shown, and we are not running in
3992         // low-level factory test mode.
3993         final ContentResolver resolver = mContext.getContentResolver();
3994         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995                 Settings.Global.getInt(resolver,
3996                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997             mCheckedForSetup = true;
3998
3999             // See if we should be showing the platform update setup UI.
4000             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003             if (!ris.isEmpty()) {
4004                 final ResolveInfo ri = ris.get(0);
4005                 String vers = ri.activityInfo.metaData != null
4006                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4007                         : null;
4008                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4010                             Intent.METADATA_SETUP_VERSION);
4011                 }
4012                 String lastVers = Settings.Secure.getString(
4013                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014                 if (vers != null && !vers.equals(lastVers)) {
4015                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016                     intent.setComponent(new ComponentName(
4017                             ri.activityInfo.packageName, ri.activityInfo.name));
4018                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020                             null, 0, 0, 0, null, false, false, null, null, null);
4021                 }
4022             }
4023         }
4024     }
4025
4026     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4028     }
4029
4030     void enforceNotIsolatedCaller(String caller) {
4031         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032             throw new SecurityException("Isolated process not allowed to call " + caller);
4033         }
4034     }
4035
4036     void enforceShellRestriction(String restriction, int userHandle) {
4037         if (Binder.getCallingUid() == Process.SHELL_UID) {
4038             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039                 throw new SecurityException("Shell does not have permission to access user "
4040                         + userHandle);
4041             }
4042         }
4043     }
4044
4045     @Override
4046     public int getFrontActivityScreenCompatMode() {
4047         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048         synchronized (this) {
4049             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4050         }
4051     }
4052
4053     @Override
4054     public void setFrontActivityScreenCompatMode(int mode) {
4055         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056                 "setFrontActivityScreenCompatMode");
4057         synchronized (this) {
4058             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4059         }
4060     }
4061
4062     @Override
4063     public int getPackageScreenCompatMode(String packageName) {
4064         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065         synchronized (this) {
4066             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4067         }
4068     }
4069
4070     @Override
4071     public void setPackageScreenCompatMode(String packageName, int mode) {
4072         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073                 "setPackageScreenCompatMode");
4074         synchronized (this) {
4075             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4076         }
4077     }
4078
4079     @Override
4080     public boolean getPackageAskScreenCompat(String packageName) {
4081         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082         synchronized (this) {
4083             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4084         }
4085     }
4086
4087     @Override
4088     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090                 "setPackageAskScreenCompat");
4091         synchronized (this) {
4092             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4093         }
4094     }
4095
4096     private boolean hasUsageStatsPermission(String callingPackage) {
4097         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098                 Binder.getCallingUid(), callingPackage);
4099         if (mode == AppOpsManager.MODE_DEFAULT) {
4100             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101                     == PackageManager.PERMISSION_GRANTED;
4102         }
4103         return mode == AppOpsManager.MODE_ALLOWED;
4104     }
4105
4106     @Override
4107     public int getPackageProcessState(String packageName, String callingPackage) {
4108         if (!hasUsageStatsPermission(callingPackage)) {
4109             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110                     "getPackageProcessState");
4111         }
4112
4113         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114         synchronized (this) {
4115             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116                 final ProcessRecord proc = mLruProcesses.get(i);
4117                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118                         || procState > proc.setProcState) {
4119                     boolean found = false;
4120                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4122                             procState = proc.setProcState;
4123                             found = true;
4124                         }
4125                     }
4126                     if (proc.pkgDeps != null && !found) {
4127                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129                                 procState = proc.setProcState;
4130                                 break;
4131                             }
4132                         }
4133                     }
4134                 }
4135             }
4136         }
4137         return procState;
4138     }
4139
4140     @Override
4141     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142         synchronized (this) {
4143             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4144             if (app == null) {
4145                 return false;
4146             }
4147             if (app.trimMemoryLevel < level && app.thread != null &&
4148                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4150                 try {
4151                     app.thread.scheduleTrimMemory(level);
4152                     app.trimMemoryLevel = level;
4153                     return true;
4154                 } catch (RemoteException e) {
4155                     // Fallthrough to failure case.
4156                 }
4157             }
4158         }
4159         return false;
4160     }
4161
4162     private void dispatchProcessesChanged() {
4163         int N;
4164         synchronized (this) {
4165             N = mPendingProcessChanges.size();
4166             if (mActiveProcessChanges.length < N) {
4167                 mActiveProcessChanges = new ProcessChangeItem[N];
4168             }
4169             mPendingProcessChanges.toArray(mActiveProcessChanges);
4170             mPendingProcessChanges.clear();
4171             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172                     "*** Delivering " + N + " process changes");
4173         }
4174
4175         int i = mProcessObservers.beginBroadcast();
4176         while (i > 0) {
4177             i--;
4178             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179             if (observer != null) {
4180                 try {
4181                     for (int j=0; j<N; j++) {
4182                         ProcessChangeItem item = mActiveProcessChanges[j];
4183                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186                                     + item.uid + ": " + item.foregroundActivities);
4187                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188                                     item.foregroundActivities);
4189                         }
4190                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193                                     + ": " + item.processState);
4194                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4195                         }
4196                     }
4197                 } catch (RemoteException e) {
4198                 }
4199             }
4200         }
4201         mProcessObservers.finishBroadcast();
4202
4203         synchronized (this) {
4204             for (int j=0; j<N; j++) {
4205                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4206             }
4207         }
4208     }
4209
4210     private void dispatchProcessDied(int pid, int uid) {
4211         int i = mProcessObservers.beginBroadcast();
4212         while (i > 0) {
4213             i--;
4214             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215             if (observer != null) {
4216                 try {
4217                     observer.onProcessDied(pid, uid);
4218                 } catch (RemoteException e) {
4219                 }
4220             }
4221         }
4222         mProcessObservers.finishBroadcast();
4223     }
4224
4225     private void dispatchUidsChanged() {
4226         int N;
4227         synchronized (this) {
4228             N = mPendingUidChanges.size();
4229             if (mActiveUidChanges.length < N) {
4230                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4231             }
4232             for (int i=0; i<N; i++) {
4233                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234                 mActiveUidChanges[i] = change;
4235                 if (change.uidRecord != null) {
4236                     change.uidRecord.pendingChange = null;
4237                     change.uidRecord = null;
4238                 }
4239             }
4240             mPendingUidChanges.clear();
4241             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242                     "*** Delivering " + N + " uid changes");
4243         }
4244
4245         if (mLocalPowerManager != null) {
4246             for (int j=0; j<N; j++) {
4247                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248                 if (item.change == UidRecord.CHANGE_GONE
4249                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250                     mLocalPowerManager.uidGone(item.uid);
4251                 } else {
4252                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4253                 }
4254             }
4255         }
4256
4257         int i = mUidObservers.beginBroadcast();
4258         while (i > 0) {
4259             i--;
4260             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262             if (observer != null) {
4263                 try {
4264                     for (int j=0; j<N; j++) {
4265                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4266                         final int change = item.change;
4267                         UidRecord validateUid = null;
4268                         if (VALIDATE_UID_STATES && i == 0) {
4269                             validateUid = mValidateUids.get(item.uid);
4270                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4271                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4272                                 validateUid = new UidRecord(item.uid);
4273                                 mValidateUids.put(item.uid, validateUid);
4274                             }
4275                         }
4276                         if (change == UidRecord.CHANGE_IDLE
4277                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4278                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280                                         "UID idle uid=" + item.uid);
4281                                 observer.onUidIdle(item.uid);
4282                             }
4283                             if (VALIDATE_UID_STATES && i == 0) {
4284                                 if (validateUid != null) {
4285                                     validateUid.idle = true;
4286                                 }
4287                             }
4288                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4289                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291                                         "UID active uid=" + item.uid);
4292                                 observer.onUidActive(item.uid);
4293                             }
4294                             if (VALIDATE_UID_STATES && i == 0) {
4295                                 validateUid.idle = false;
4296                             }
4297                         }
4298                         if (change == UidRecord.CHANGE_GONE
4299                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4300                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302                                         "UID gone uid=" + item.uid);
4303                                 observer.onUidGone(item.uid);
4304                             }
4305                             if (VALIDATE_UID_STATES && i == 0) {
4306                                 if (validateUid != null) {
4307                                     mValidateUids.remove(item.uid);
4308                                 }
4309                             }
4310                         } else {
4311                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313                                         "UID CHANGED uid=" + item.uid
4314                                                 + ": " + item.processState);
4315                                 observer.onUidStateChanged(item.uid, item.processState);
4316                             }
4317                             if (VALIDATE_UID_STATES && i == 0) {
4318                                 validateUid.curProcState = validateUid.setProcState
4319                                         = item.processState;
4320                             }
4321                         }
4322                     }
4323                 } catch (RemoteException e) {
4324                 }
4325             }
4326         }
4327         mUidObservers.finishBroadcast();
4328
4329         synchronized (this) {
4330             for (int j=0; j<N; j++) {
4331                 mAvailUidChanges.add(mActiveUidChanges[j]);
4332             }
4333         }
4334     }
4335
4336     @Override
4337     public final int startActivity(IApplicationThread caller, String callingPackage,
4338             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342                 UserHandle.getCallingUserId());
4343     }
4344
4345     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4350
4351         // TODO: Switch to user app stacks here.
4352         String mimeType = intent.getType();
4353         final Uri data = intent.getData();
4354         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355             mimeType = getProviderMimeType(data, userId);
4356         }
4357         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4358
4359         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361                 null, 0, 0, null, null, null, null, false, userId, container, null);
4362     }
4363
4364     @Override
4365     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368         enforceNotIsolatedCaller("startActivity");
4369         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371         // TODO: Switch to user app stacks here.
4372         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374                 profilerInfo, null, null, bOptions, false, userId, null, null);
4375     }
4376
4377     @Override
4378     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4381             int userId) {
4382
4383         // This is very dangerous -- it allows you to perform a start activity (including
4384         // permission grants) as any app that may launch one of your own activities.  So
4385         // we will only allow this to be done from activities that are part of the core framework,
4386         // and then only when they are running as the system.
4387         final ActivityRecord sourceRecord;
4388         final int targetUid;
4389         final String targetPackage;
4390         synchronized (this) {
4391             if (resultTo == null) {
4392                 throw new SecurityException("Must be called from an activity");
4393             }
4394             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395             if (sourceRecord == null) {
4396                 throw new SecurityException("Called with bad activity token: " + resultTo);
4397             }
4398             if (!sourceRecord.info.packageName.equals("android")) {
4399                 throw new SecurityException(
4400                         "Must be called from an activity that is declared in the android package");
4401             }
4402             if (sourceRecord.app == null) {
4403                 throw new SecurityException("Called without a process attached to activity");
4404             }
4405             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406                 // This is still okay, as long as this activity is running under the
4407                 // uid of the original calling activity.
4408                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409                     throw new SecurityException(
4410                             "Calling activity in uid " + sourceRecord.app.uid
4411                                     + " must be system uid or original calling uid "
4412                                     + sourceRecord.launchedFromUid);
4413                 }
4414             }
4415             if (ignoreTargetSecurity) {
4416                 if (intent.getComponent() == null) {
4417                     throw new SecurityException(
4418                             "Component must be specified with ignoreTargetSecurity");
4419                 }
4420                 if (intent.getSelector() != null) {
4421                     throw new SecurityException(
4422                             "Selector not allowed with ignoreTargetSecurity");
4423                 }
4424             }
4425             targetUid = sourceRecord.launchedFromUid;
4426             targetPackage = sourceRecord.launchedFromPackage;
4427         }
4428
4429         if (userId == UserHandle.USER_NULL) {
4430             userId = UserHandle.getUserId(sourceRecord.app.uid);
4431         }
4432
4433         // TODO: Switch to user app stacks here.
4434         try {
4435             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4438             return ret;
4439         } catch (SecurityException e) {
4440             // XXX need to figure out how to propagate to original app.
4441             // A SecurityException here is generally actually a fault of the original
4442             // calling activity (such as a fairly granting permissions), so propagate it
4443             // back to them.
4444             /*
4445             StringBuilder msg = new StringBuilder();
4446             msg.append("While launching");
4447             msg.append(intent.toString());
4448             msg.append(": ");
4449             msg.append(e.getMessage());
4450             */
4451             throw e;
4452         }
4453     }
4454
4455     @Override
4456     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459         enforceNotIsolatedCaller("startActivityAndWait");
4460         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462         WaitResult res = new WaitResult();
4463         // TODO: Switch to user app stacks here.
4464         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466                 bOptions, false, userId, null, null);
4467         return res;
4468     }
4469
4470     @Override
4471     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473             int startFlags, Configuration config, Bundle bOptions, int userId) {
4474         enforceNotIsolatedCaller("startActivityWithConfig");
4475         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477         // TODO: Switch to user app stacks here.
4478         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480                 null, null, config, bOptions, false, userId, null, null);
4481         return ret;
4482     }
4483
4484     @Override
4485     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488             throws TransactionTooLargeException {
4489         enforceNotIsolatedCaller("startActivityIntentSender");
4490         // Refuse possible leaked file descriptors
4491         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492             throw new IllegalArgumentException("File descriptors passed in Intent");
4493         }
4494
4495         IIntentSender sender = intent.getTarget();
4496         if (!(sender instanceof PendingIntentRecord)) {
4497             throw new IllegalArgumentException("Bad PendingIntent object");
4498         }
4499
4500         PendingIntentRecord pir = (PendingIntentRecord)sender;
4501
4502         synchronized (this) {
4503             // If this is coming from the currently resumed activity, it is
4504             // effectively saying that app switches are allowed at this point.
4505             final ActivityStack stack = getFocusedStack();
4506             if (stack.mResumedActivity != null &&
4507                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508                 mAppSwitchesAllowedTime = 0;
4509             }
4510         }
4511         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4513         return ret;
4514     }
4515
4516     @Override
4517     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518             Intent intent, String resolvedType, IVoiceInteractionSession session,
4519             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520             Bundle bOptions, int userId) {
4521         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522                 != PackageManager.PERMISSION_GRANTED) {
4523             String msg = "Permission Denial: startVoiceActivity() from pid="
4524                     + Binder.getCallingPid()
4525                     + ", uid=" + Binder.getCallingUid()
4526                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4527             Slog.w(TAG, msg);
4528             throw new SecurityException(msg);
4529         }
4530         if (session == null || interactor == null) {
4531             throw new NullPointerException("null session or interactor");
4532         }
4533         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535         // TODO: Switch to user app stacks here.
4536         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538                 null, bOptions, false, userId, null, null);
4539     }
4540
4541     @Override
4542     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543             throws RemoteException {
4544         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545         synchronized (this) {
4546             ActivityRecord activity = getFocusedStack().topActivity();
4547             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4549             }
4550             if (mRunningVoice != null || activity.task.voiceSession != null
4551                     || activity.voiceSession != null) {
4552                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4553                 return;
4554             }
4555             if (activity.pendingVoiceInteractionStart) {
4556                 Slog.w(TAG, "Pending start of voice interaction already.");
4557                 return;
4558             }
4559             activity.pendingVoiceInteractionStart = true;
4560         }
4561         LocalServices.getService(VoiceInteractionManagerInternal.class)
4562                 .startLocalVoiceInteraction(callingActivity, options);
4563     }
4564
4565     @Override
4566     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567         LocalServices.getService(VoiceInteractionManagerInternal.class)
4568                 .stopLocalVoiceInteraction(callingActivity);
4569     }
4570
4571     @Override
4572     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574                 .supportsLocalVoiceInteraction();
4575     }
4576
4577     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580         if (activityToCallback == null) return;
4581         activityToCallback.setVoiceSessionLocked(voiceSession);
4582
4583         // Inform the activity
4584         try {
4585             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4586                     voiceInteractor);
4587             long token = Binder.clearCallingIdentity();
4588             try {
4589                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4590             } finally {
4591                 Binder.restoreCallingIdentity(token);
4592             }
4593             // TODO: VI Should we cache the activity so that it's easier to find later
4594             // rather than scan through all the stacks and activities?
4595         } catch (RemoteException re) {
4596             activityToCallback.clearVoiceSessionLocked();
4597             // TODO: VI Should this terminate the voice session?
4598         }
4599     }
4600
4601     @Override
4602     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603         synchronized (this) {
4604             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4605                 if (keepAwake) {
4606                     mVoiceWakeLock.acquire();
4607                 } else {
4608                     mVoiceWakeLock.release();
4609                 }
4610             }
4611         }
4612     }
4613
4614     @Override
4615     public boolean startNextMatchingActivity(IBinder callingActivity,
4616             Intent intent, Bundle bOptions) {
4617         // Refuse possible leaked file descriptors
4618         if (intent != null && intent.hasFileDescriptors() == true) {
4619             throw new IllegalArgumentException("File descriptors passed in Intent");
4620         }
4621         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4622
4623         synchronized (this) {
4624             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4625             if (r == null) {
4626                 ActivityOptions.abort(options);
4627                 return false;
4628             }
4629             if (r.app == null || r.app.thread == null) {
4630                 // The caller is not running...  d'oh!
4631                 ActivityOptions.abort(options);
4632                 return false;
4633             }
4634             intent = new Intent(intent);
4635             // The caller is not allowed to change the data.
4636             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637             // And we are resetting to find the next component...
4638             intent.setComponent(null);
4639
4640             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4641
4642             ActivityInfo aInfo = null;
4643             try {
4644                 List<ResolveInfo> resolves =
4645                     AppGlobals.getPackageManager().queryIntentActivities(
4646                             intent, r.resolvedType,
4647                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648                             UserHandle.getCallingUserId()).getList();
4649
4650                 // Look for the original activity in the list...
4651                 final int N = resolves != null ? resolves.size() : 0;
4652                 for (int i=0; i<N; i++) {
4653                     ResolveInfo rInfo = resolves.get(i);
4654                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4655                             && rInfo.activityInfo.name.equals(r.info.name)) {
4656                         // We found the current one...  the next matching is
4657                         // after it.
4658                         i++;
4659                         if (i<N) {
4660                             aInfo = resolves.get(i).activityInfo;
4661                         }
4662                         if (debug) {
4663                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664                                     + "/" + r.info.name);
4665                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4667                         }
4668                         break;
4669                     }
4670                 }
4671             } catch (RemoteException e) {
4672             }
4673
4674             if (aInfo == null) {
4675                 // Nobody who is next!
4676                 ActivityOptions.abort(options);
4677                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4678                 return false;
4679             }
4680
4681             intent.setComponent(new ComponentName(
4682                     aInfo.applicationInfo.packageName, aInfo.name));
4683             intent.setFlags(intent.getFlags()&~(
4684                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687                     Intent.FLAG_ACTIVITY_NEW_TASK));
4688
4689             // Okay now we need to start the new activity, replacing the
4690             // currently running activity.  This is a little tricky because
4691             // we want to start the new one as if the current one is finished,
4692             // but not finish the current one first so that there is no flicker.
4693             // And thus...
4694             final boolean wasFinishing = r.finishing;
4695             r.finishing = true;
4696
4697             // Propagate reply information over to the new activity.
4698             final ActivityRecord resultTo = r.resultTo;
4699             final String resultWho = r.resultWho;
4700             final int requestCode = r.requestCode;
4701             r.resultTo = null;
4702             if (resultTo != null) {
4703                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4704             }
4705
4706             final long origId = Binder.clearCallingIdentity();
4707             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711                     false, false, null, null, null);
4712             Binder.restoreCallingIdentity(origId);
4713
4714             r.finishing = wasFinishing;
4715             if (res != ActivityManager.START_SUCCESS) {
4716                 return false;
4717             }
4718             return true;
4719         }
4720     }
4721
4722     @Override
4723     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725             String msg = "Permission Denial: startActivityFromRecents called without " +
4726                     START_TASKS_FROM_RECENTS;
4727             Slog.w(TAG, msg);
4728             throw new SecurityException(msg);
4729         }
4730         final long origId = Binder.clearCallingIdentity();
4731         try {
4732             synchronized (this) {
4733                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4734             }
4735         } finally {
4736             Binder.restoreCallingIdentity(origId);
4737         }
4738     }
4739
4740     final int startActivityInPackage(int uid, String callingPackage,
4741             Intent intent, String resolvedType, IBinder resultTo,
4742             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743             IActivityContainer container, TaskRecord inTask) {
4744
4745         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4747
4748         // TODO: Switch to user app stacks here.
4749         int ret = mActivityStarter.startActivityMayWait(null, uid, ActivityStarter.PID_NULL, uid,
4750                 callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode,
4751                 startFlags, null, null, null, bOptions, false, userId, container, inTask);
4752         return ret;
4753     }
4754
4755     @Override
4756     public final int startActivities(IApplicationThread caller, String callingPackage,
4757             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4758             int userId) {
4759         enforceNotIsolatedCaller("startActivities");
4760         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762         // TODO: Switch to user app stacks here.
4763         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764                 resolvedTypes, resultTo, bOptions, userId);
4765         return ret;
4766     }
4767
4768     final int startActivitiesInPackage(int uid, String callingPackage,
4769             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770             Bundle bOptions, int userId) {
4771         return startActivitiesInPackage(uid, ActivityStarter.PID_NULL, UserHandle.USER_NULL,
4772                 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4773     }
4774
4775     final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
4776                                        String callingPackage, Intent[] intents, String[] resolvedTypes,
4777                                        IBinder resultTo, Bundle bOptions, int userId) {
4778
4779         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4780                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4781         // TODO: Switch to user app stacks here.
4782         int ret = mActivityStarter.startActivities(null, uid, realCallingPid, realCallingUid,
4783                 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4784         return ret;
4785     }
4786
4787     @Override
4788     public void reportActivityFullyDrawn(IBinder token) {
4789         synchronized (this) {
4790             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4791             if (r == null) {
4792                 return;
4793             }
4794             r.reportFullyDrawnLocked();
4795         }
4796     }
4797
4798     @Override
4799     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4800         synchronized (this) {
4801             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4802             if (r == null) {
4803                 return;
4804             }
4805             TaskRecord task = r.task;
4806             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4807                 // Fixed screen orientation isn't supported when activities aren't in full screen
4808                 // mode.
4809                 return;
4810             }
4811             final long origId = Binder.clearCallingIdentity();
4812             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4813             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4814                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4815             if (config != null) {
4816                 r.frozenBeforeDestroy = true;
4817                 if (!updateConfigurationLocked(config, r, false)) {
4818                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4819                 }
4820             }
4821             Binder.restoreCallingIdentity(origId);
4822         }
4823     }
4824
4825     @Override
4826     public int getRequestedOrientation(IBinder token) {
4827         synchronized (this) {
4828             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4829             if (r == null) {
4830                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4831             }
4832             return mWindowManager.getAppOrientation(r.appToken);
4833         }
4834     }
4835
4836     /**
4837      * This is the internal entry point for handling Activity.finish().
4838      *
4839      * @param token The Binder token referencing the Activity we want to finish.
4840      * @param resultCode Result code, if any, from this Activity.
4841      * @param resultData Result data (Intent), if any, from this Activity.
4842      * @param finishTask Whether to finish the task associated with this Activity.
4843      *
4844      * @return Returns true if the activity successfully finished, or false if it is still running.
4845      */
4846     @Override
4847     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4848             int finishTask) {
4849         // Refuse possible leaked file descriptors
4850         if (resultData != null && resultData.hasFileDescriptors() == true) {
4851             throw new IllegalArgumentException("File descriptors passed in Intent");
4852         }
4853
4854         synchronized(this) {
4855             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4856             if (r == null) {
4857                 return true;
4858             }
4859             // Keep track of the root activity of the task before we finish it
4860             TaskRecord tr = r.task;
4861             ActivityRecord rootR = tr.getRootActivity();
4862             if (rootR == null) {
4863                 Slog.w(TAG, "Finishing task with all activities already finished");
4864             }
4865             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4866             // finish.
4867             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4868                     mStackSupervisor.isLastLockedTask(tr)) {
4869                 Slog.i(TAG, "Not finishing task in lock task mode");
4870                 mStackSupervisor.showLockTaskToast();
4871                 return false;
4872             }
4873             if (mController != null) {
4874                 // Find the first activity that is not finishing.
4875                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4876                 if (next != null) {
4877                     // ask watcher if this is allowed
4878                     boolean resumeOK = true;
4879                     try {
4880                         resumeOK = mController.activityResuming(next.packageName);
4881                     } catch (RemoteException e) {
4882                         mController = null;
4883                         Watchdog.getInstance().setActivityController(null);
4884                     }
4885
4886                     if (!resumeOK) {
4887                         Slog.i(TAG, "Not finishing activity because controller resumed");
4888                         return false;
4889                     }
4890                 }
4891             }
4892             final long origId = Binder.clearCallingIdentity();
4893             try {
4894                 boolean res;
4895                 final boolean finishWithRootActivity =
4896                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4897                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4898                         || (finishWithRootActivity && r == rootR)) {
4899                     // If requested, remove the task that is associated to this activity only if it
4900                     // was the root activity in the task. The result code and data is ignored
4901                     // because we don't support returning them across task boundaries. Also, to
4902                     // keep backwards compatibility we remove the task from recents when finishing
4903                     // task with root activity.
4904                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4905                     if (!res) {
4906                         Slog.i(TAG, "Removing task failed to finish activity");
4907                     }
4908                 } else {
4909                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4910                             resultData, "app-request", true);
4911                     if (!res) {
4912                         Slog.i(TAG, "Failed to finish by app-request");
4913                     }
4914                 }
4915                 return res;
4916             } finally {
4917                 Binder.restoreCallingIdentity(origId);
4918             }
4919         }
4920     }
4921
4922     @Override
4923     public final void finishHeavyWeightApp() {
4924         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4925                 != PackageManager.PERMISSION_GRANTED) {
4926             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4927                     + Binder.getCallingPid()
4928                     + ", uid=" + Binder.getCallingUid()
4929                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4930             Slog.w(TAG, msg);
4931             throw new SecurityException(msg);
4932         }
4933
4934         synchronized(this) {
4935             if (mHeavyWeightProcess == null) {
4936                 return;
4937             }
4938
4939             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4940             for (int i = 0; i < activities.size(); i++) {
4941                 ActivityRecord r = activities.get(i);
4942                 if (!r.finishing && r.isInStackLocked()) {
4943                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4944                             null, "finish-heavy", true);
4945                 }
4946             }
4947
4948             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4949                     mHeavyWeightProcess.userId, 0));
4950             mHeavyWeightProcess = null;
4951         }
4952     }
4953
4954     @Override
4955     public void crashApplication(int uid, int initialPid, String packageName,
4956             String message) {
4957         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4958                 != PackageManager.PERMISSION_GRANTED) {
4959             String msg = "Permission Denial: crashApplication() from pid="
4960                     + Binder.getCallingPid()
4961                     + ", uid=" + Binder.getCallingUid()
4962                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4963             Slog.w(TAG, msg);
4964             throw new SecurityException(msg);
4965         }
4966
4967         synchronized(this) {
4968             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4969         }
4970     }
4971
4972     @Override
4973     public final void finishSubActivity(IBinder token, String resultWho,
4974             int requestCode) {
4975         synchronized(this) {
4976             final long origId = Binder.clearCallingIdentity();
4977             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4978             if (r != null) {
4979                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4980             }
4981             Binder.restoreCallingIdentity(origId);
4982         }
4983     }
4984
4985     @Override
4986     public boolean finishActivityAffinity(IBinder token) {
4987         synchronized(this) {
4988             final long origId = Binder.clearCallingIdentity();
4989             try {
4990                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991                 if (r == null) {
4992                     return false;
4993                 }
4994
4995                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4996                 // can finish.
4997                 final TaskRecord task = r.task;
4998                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4999                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5000                     mStackSupervisor.showLockTaskToast();
5001                     return false;
5002                 }
5003                 return task.stack.finishActivityAffinityLocked(r);
5004             } finally {
5005                 Binder.restoreCallingIdentity(origId);
5006             }
5007         }
5008     }
5009
5010     @Override
5011     public void finishVoiceTask(IVoiceInteractionSession session) {
5012         synchronized (this) {
5013             final long origId = Binder.clearCallingIdentity();
5014             try {
5015                 // TODO: VI Consider treating local voice interactions and voice tasks
5016                 // differently here
5017                 mStackSupervisor.finishVoiceTask(session);
5018             } finally {
5019                 Binder.restoreCallingIdentity(origId);
5020             }
5021         }
5022
5023     }
5024
5025     @Override
5026     public boolean releaseActivityInstance(IBinder token) {
5027         synchronized(this) {
5028             final long origId = Binder.clearCallingIdentity();
5029             try {
5030                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5031                 if (r == null) {
5032                     return false;
5033                 }
5034                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5035             } finally {
5036                 Binder.restoreCallingIdentity(origId);
5037             }
5038         }
5039     }
5040
5041     @Override
5042     public void releaseSomeActivities(IApplicationThread appInt) {
5043         synchronized(this) {
5044             final long origId = Binder.clearCallingIdentity();
5045             try {
5046                 ProcessRecord app = getRecordForAppLocked(appInt);
5047                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5048             } finally {
5049                 Binder.restoreCallingIdentity(origId);
5050             }
5051         }
5052     }
5053
5054     @Override
5055     public boolean willActivityBeVisible(IBinder token) {
5056         synchronized(this) {
5057             ActivityStack stack = ActivityRecord.getStackLocked(token);
5058             if (stack != null) {
5059                 return stack.willActivityBeVisibleLocked(token);
5060             }
5061             return false;
5062         }
5063     }
5064
5065     @Override
5066     public void overridePendingTransition(IBinder token, String packageName,
5067             int enterAnim, int exitAnim) {
5068         synchronized(this) {
5069             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5070             if (self == null) {
5071                 return;
5072             }
5073
5074             final long origId = Binder.clearCallingIdentity();
5075
5076             if (self.state == ActivityState.RESUMED
5077                     || self.state == ActivityState.PAUSING) {
5078                 mWindowManager.overridePendingAppTransition(packageName,
5079                         enterAnim, exitAnim, null);
5080             }
5081
5082             Binder.restoreCallingIdentity(origId);
5083         }
5084     }
5085
5086     /**
5087      * Main function for removing an existing process from the activity manager
5088      * as a result of that process going away.  Clears out all connections
5089      * to the process.
5090      */
5091     private final void handleAppDiedLocked(ProcessRecord app,
5092             boolean restarting, boolean allowRestart) {
5093         int pid = app.pid;
5094         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5095                 false /*replacingPid*/);
5096         if (!kept && !restarting) {
5097             removeLruProcessLocked(app);
5098             if (pid > 0) {
5099                 ProcessList.remove(pid);
5100             }
5101         }
5102
5103         if (mProfileProc == app) {
5104             clearProfilerLocked();
5105         }
5106
5107         // Remove this application's activities from active lists.
5108         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5109
5110         app.activities.clear();
5111
5112         if (app.instrumentationClass != null) {
5113             Slog.w(TAG, "Crash of app " + app.processName
5114                   + " running instrumentation " + app.instrumentationClass);
5115             Bundle info = new Bundle();
5116             info.putString("shortMsg", "Process crashed.");
5117             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5118         }
5119
5120         if (!restarting && hasVisibleActivities
5121                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5122             // If there was nothing to resume, and we are not already restarting this process, but
5123             // there is a visible activity that is hosted by the process...  then make sure all
5124             // visible activities are running, taking care of restarting this process.
5125             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5126         }
5127     }
5128
5129     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5130         IBinder threadBinder = thread.asBinder();
5131         // Find the application record.
5132         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5133             ProcessRecord rec = mLruProcesses.get(i);
5134             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5135                 return i;
5136             }
5137         }
5138         return -1;
5139     }
5140
5141     final ProcessRecord getRecordForAppLocked(
5142             IApplicationThread thread) {
5143         if (thread == null) {
5144             return null;
5145         }
5146
5147         int appIndex = getLRURecordIndexForAppLocked(thread);
5148         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5149     }
5150
5151     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5152         // If there are no longer any background processes running,
5153         // and the app that died was not running instrumentation,
5154         // then tell everyone we are now low on memory.
5155         boolean haveBg = false;
5156         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5157             ProcessRecord rec = mLruProcesses.get(i);
5158             if (rec.thread != null
5159                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5160                 haveBg = true;
5161                 break;
5162             }
5163         }
5164
5165         if (!haveBg) {
5166             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5167             if (doReport) {
5168                 long now = SystemClock.uptimeMillis();
5169                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5170                     doReport = false;
5171                 } else {
5172                     mLastMemUsageReportTime = now;
5173                 }
5174             }
5175             final ArrayList<ProcessMemInfo> memInfos
5176                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5177             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5178             long now = SystemClock.uptimeMillis();
5179             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5180                 ProcessRecord rec = mLruProcesses.get(i);
5181                 if (rec == dyingProc || rec.thread == null) {
5182                     continue;
5183                 }
5184                 if (doReport) {
5185                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5186                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5187                 }
5188                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5189                     // The low memory report is overriding any current
5190                     // state for a GC request.  Make sure to do
5191                     // heavy/important/visible/foreground processes first.
5192                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5193                         rec.lastRequestedGc = 0;
5194                     } else {
5195                         rec.lastRequestedGc = rec.lastLowMemory;
5196                     }
5197                     rec.reportLowMemory = true;
5198                     rec.lastLowMemory = now;
5199                     mProcessesToGc.remove(rec);
5200                     addProcessToGcListLocked(rec);
5201                 }
5202             }
5203             if (doReport) {
5204                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5205                 mHandler.sendMessage(msg);
5206             }
5207             scheduleAppGcsLocked();
5208         }
5209     }
5210
5211     final void appDiedLocked(ProcessRecord app) {
5212        appDiedLocked(app, app.pid, app.thread, false);
5213     }
5214
5215     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5216             boolean fromBinderDied) {
5217         // First check if this ProcessRecord is actually active for the pid.
5218         synchronized (mPidsSelfLocked) {
5219             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5220             if (curProc != app) {
5221                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5222                 return;
5223             }
5224         }
5225
5226         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5227         synchronized (stats) {
5228             stats.noteProcessDiedLocked(app.info.uid, pid);
5229         }
5230
5231         if (!app.killed) {
5232             if (!fromBinderDied) {
5233                 Process.killProcessQuiet(pid);
5234             }
5235             killProcessGroup(app.uid, pid);
5236             app.killed = true;
5237         }
5238
5239         // Clean up already done if the process has been re-started.
5240         if (app.pid == pid && app.thread != null &&
5241                 app.thread.asBinder() == thread.asBinder()) {
5242             boolean doLowMem = app.instrumentationClass == null;
5243             boolean doOomAdj = doLowMem;
5244             if (!app.killedByAm) {
5245                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5246                         + ") has died");
5247                 mAllowLowerMemLevel = true;
5248             } else {
5249                 // Note that we always want to do oom adj to update our state with the
5250                 // new number of procs.
5251                 mAllowLowerMemLevel = false;
5252                 doLowMem = false;
5253             }
5254             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5255             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5256                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5257             handleAppDiedLocked(app, false, true);
5258
5259             if (doOomAdj) {
5260                 updateOomAdjLocked();
5261             }
5262             if (doLowMem) {
5263                 doLowMemReportIfNeededLocked(app);
5264             }
5265         } else if (app.pid != pid) {
5266             // A new process has already been started.
5267             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5268                     + ") has died and restarted (pid " + app.pid + ").");
5269             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5270         } else if (DEBUG_PROCESSES) {
5271             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5272                     + thread.asBinder());
5273         }
5274     }
5275
5276     /**
5277      * If a stack trace dump file is configured, dump process stack traces.
5278      * @param clearTraces causes the dump file to be erased prior to the new
5279      *    traces being written, if true; when false, the new traces will be
5280      *    appended to any existing file content.
5281      * @param firstPids of dalvik VM processes to dump stack traces for first
5282      * @param lastPids of dalvik VM processes to dump stack traces for last
5283      * @param nativeProcs optional list of native process names to dump stack crawls
5284      * @return file containing stack traces, or null if no dump file is configured
5285      */
5286     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5287             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5288         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5289         if (tracesPath == null || tracesPath.length() == 0) {
5290             return null;
5291         }
5292
5293         File tracesFile = new File(tracesPath);
5294         try {
5295             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5296             tracesFile.createNewFile();
5297             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5298         } catch (IOException e) {
5299             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5300             return null;
5301         }
5302
5303         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5304         return tracesFile;
5305     }
5306
5307     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5308             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5309         // Use a FileObserver to detect when traces finish writing.
5310         // The order of traces is considered important to maintain for legibility.
5311         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5312             @Override
5313             public synchronized void onEvent(int event, String path) { notify(); }
5314         };
5315
5316         try {
5317             observer.startWatching();
5318
5319             // First collect all of the stacks of the most important pids.
5320             if (firstPids != null) {
5321                 try {
5322                     int num = firstPids.size();
5323                     for (int i = 0; i < num; i++) {
5324                         synchronized (observer) {
5325                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5326                                     + firstPids.get(i));
5327                             final long sime = SystemClock.elapsedRealtime();
5328                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5329                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5330                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5331                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5332                         }
5333                     }
5334                 } catch (InterruptedException e) {
5335                     Slog.wtf(TAG, e);
5336                 }
5337             }
5338
5339             // Next collect the stacks of the native pids
5340             if (nativeProcs != null) {
5341                 int[] pids = Process.getPidsForCommands(nativeProcs);
5342                 if (pids != null) {
5343                     for (int pid : pids) {
5344                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5345                         final long sime = SystemClock.elapsedRealtime();
5346                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5347                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5348                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5349                     }
5350                 }
5351             }
5352
5353             // Lastly, measure CPU usage.
5354             if (processCpuTracker != null) {
5355                 processCpuTracker.init();
5356                 System.gc();
5357                 processCpuTracker.update();
5358                 try {
5359                     synchronized (processCpuTracker) {
5360                         processCpuTracker.wait(500); // measure over 1/2 second.
5361                     }
5362                 } catch (InterruptedException e) {
5363                 }
5364                 processCpuTracker.update();
5365
5366                 // We'll take the stack crawls of just the top apps using CPU.
5367                 final int N = processCpuTracker.countWorkingStats();
5368                 int numProcs = 0;
5369                 for (int i=0; i<N && numProcs<5; i++) {
5370                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5371                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5372                         numProcs++;
5373                         try {
5374                             synchronized (observer) {
5375                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5376                                         + stats.pid);
5377                                 final long stime = SystemClock.elapsedRealtime();
5378                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5379                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5380                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5381                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5382                             }
5383                         } catch (InterruptedException e) {
5384                             Slog.wtf(TAG, e);
5385                         }
5386                     } else if (DEBUG_ANR) {
5387                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5388                                 + stats.pid);
5389                     }
5390                 }
5391             }
5392         } finally {
5393             observer.stopWatching();
5394         }
5395     }
5396
5397     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5398         if (true || IS_USER_BUILD) {
5399             return;
5400         }
5401         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5402         if (tracesPath == null || tracesPath.length() == 0) {
5403             return;
5404         }
5405
5406         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5407         StrictMode.allowThreadDiskWrites();
5408         try {
5409             final File tracesFile = new File(tracesPath);
5410             final File tracesDir = tracesFile.getParentFile();
5411             final File tracesTmp = new File(tracesDir, "__tmp__");
5412             try {
5413                 if (tracesFile.exists()) {
5414                     tracesTmp.delete();
5415                     tracesFile.renameTo(tracesTmp);
5416                 }
5417                 StringBuilder sb = new StringBuilder();
5418                 Time tobj = new Time();
5419                 tobj.set(System.currentTimeMillis());
5420                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5421                 sb.append(": ");
5422                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5423                 sb.append(" since ");
5424                 sb.append(msg);
5425                 FileOutputStream fos = new FileOutputStream(tracesFile);
5426                 fos.write(sb.toString().getBytes());
5427                 if (app == null) {
5428                     fos.write("\n*** No application process!".getBytes());
5429                 }
5430                 fos.close();
5431                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5432             } catch (IOException e) {
5433                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5434                 return;
5435             }
5436
5437             if (app != null) {
5438                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5439                 firstPids.add(app.pid);
5440                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5441             }
5442
5443             File lastTracesFile = null;
5444             File curTracesFile = null;
5445             for (int i=9; i>=0; i--) {
5446                 String name = String.format(Locale.US, "slow%02d.txt", i);
5447                 curTracesFile = new File(tracesDir, name);
5448                 if (curTracesFile.exists()) {
5449                     if (lastTracesFile != null) {
5450                         curTracesFile.renameTo(lastTracesFile);
5451                     } else {
5452                         curTracesFile.delete();
5453                     }
5454                 }
5455                 lastTracesFile = curTracesFile;
5456             }
5457             tracesFile.renameTo(curTracesFile);
5458             if (tracesTmp.exists()) {
5459                 tracesTmp.renameTo(tracesFile);
5460             }
5461         } finally {
5462             StrictMode.setThreadPolicy(oldPolicy);
5463         }
5464     }
5465
5466     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5467         if (!mLaunchWarningShown) {
5468             mLaunchWarningShown = true;
5469             mUiHandler.post(new Runnable() {
5470                 @Override
5471                 public void run() {
5472                     synchronized (ActivityManagerService.this) {
5473                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5474                         d.show();
5475                         mUiHandler.postDelayed(new Runnable() {
5476                             @Override
5477                             public void run() {
5478                                 synchronized (ActivityManagerService.this) {
5479                                     d.dismiss();
5480                                     mLaunchWarningShown = false;
5481                                 }
5482                             }
5483                         }, 4000);
5484                     }
5485                 }
5486             });
5487         }
5488     }
5489
5490     @Override
5491     public boolean clearApplicationUserData(final String packageName,
5492             final IPackageDataObserver observer, int userId) {
5493         enforceNotIsolatedCaller("clearApplicationUserData");
5494         int uid = Binder.getCallingUid();
5495         int pid = Binder.getCallingPid();
5496         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5497                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5498
5499
5500         long callingId = Binder.clearCallingIdentity();
5501         try {
5502             IPackageManager pm = AppGlobals.getPackageManager();
5503             int pkgUid = -1;
5504             synchronized(this) {
5505                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5506                         userId, packageName)) {
5507                     throw new SecurityException(
5508                             "Cannot clear data for a protected package: " + packageName);
5509                 }
5510
5511                 try {
5512                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5513                 } catch (RemoteException e) {
5514                 }
5515                 if (pkgUid == -1) {
5516                     Slog.w(TAG, "Invalid packageName: " + packageName);
5517                     if (observer != null) {
5518                         try {
5519                             observer.onRemoveCompleted(packageName, false);
5520                         } catch (RemoteException e) {
5521                             Slog.i(TAG, "Observer no longer exists.");
5522                         }
5523                     }
5524                     return false;
5525                 }
5526                 if (uid == pkgUid || checkComponentPermission(
5527                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5528                         pid, uid, -1, true)
5529                         == PackageManager.PERMISSION_GRANTED) {
5530                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5531                 } else {
5532                     throw new SecurityException("PID " + pid + " does not have permission "
5533                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5534                                     + " of package " + packageName);
5535                 }
5536
5537                 // Remove all tasks match the cleared application package and user
5538                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5539                     final TaskRecord tr = mRecentTasks.get(i);
5540                     final String taskPackageName =
5541                             tr.getBaseIntent().getComponent().getPackageName();
5542                     if (tr.userId != userId) continue;
5543                     if (!taskPackageName.equals(packageName)) continue;
5544                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5545                 }
5546             }
5547
5548             final int pkgUidF = pkgUid;
5549             final int userIdF = userId;
5550             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5551                 @Override
5552                 public void onRemoveCompleted(String packageName, boolean succeeded)
5553                         throws RemoteException {
5554                     synchronized (ActivityManagerService.this) {
5555                         finishForceStopPackageLocked(packageName, pkgUidF);
5556                     }
5557
5558                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5559                             Uri.fromParts("package", packageName, null));
5560                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5561                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5562                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5563                             null, null, 0, null, null, null, null, false, false, userIdF);
5564
5565                     if (observer != null) {
5566                         observer.onRemoveCompleted(packageName, succeeded);
5567                     }
5568                 }
5569             };
5570
5571             try {
5572                 // Clear application user data
5573                 pm.clearApplicationUserData(packageName, localObserver, userId);
5574
5575                 synchronized(this) {
5576                     // Remove all permissions granted from/to this package
5577                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5578                 }
5579
5580                 // Remove all zen rules created by this package; revoke it's zen access.
5581                 INotificationManager inm = NotificationManager.getService();
5582                 inm.removeAutomaticZenRules(packageName);
5583                 inm.setNotificationPolicyAccessGranted(packageName, false);
5584
5585             } catch (RemoteException e) {
5586             }
5587         } finally {
5588             Binder.restoreCallingIdentity(callingId);
5589         }
5590         return true;
5591     }
5592
5593     @Override
5594     public void killBackgroundProcesses(final String packageName, int userId) {
5595         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5596                 != PackageManager.PERMISSION_GRANTED &&
5597                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5598                         != PackageManager.PERMISSION_GRANTED) {
5599             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5600                     + Binder.getCallingPid()
5601                     + ", uid=" + Binder.getCallingUid()
5602                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5603             Slog.w(TAG, msg);
5604             throw new SecurityException(msg);
5605         }
5606
5607         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5608                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5609         long callingId = Binder.clearCallingIdentity();
5610         try {
5611             IPackageManager pm = AppGlobals.getPackageManager();
5612             synchronized(this) {
5613                 int appId = -1;
5614                 try {
5615                     appId = UserHandle.getAppId(
5616                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5617                 } catch (RemoteException e) {
5618                 }
5619                 if (appId == -1) {
5620                     Slog.w(TAG, "Invalid packageName: " + packageName);
5621                     return;
5622                 }
5623                 killPackageProcessesLocked(packageName, appId, userId,
5624                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5625             }
5626         } finally {
5627             Binder.restoreCallingIdentity(callingId);
5628         }
5629     }
5630
5631     @Override
5632     public void killAllBackgroundProcesses() {
5633         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5634                 != PackageManager.PERMISSION_GRANTED) {
5635             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5636                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5637                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5638             Slog.w(TAG, msg);
5639             throw new SecurityException(msg);
5640         }
5641
5642         final long callingId = Binder.clearCallingIdentity();
5643         try {
5644             synchronized (this) {
5645                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5646                 final int NP = mProcessNames.getMap().size();
5647                 for (int ip = 0; ip < NP; ip++) {
5648                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5649                     final int NA = apps.size();
5650                     for (int ia = 0; ia < NA; ia++) {
5651                         final ProcessRecord app = apps.valueAt(ia);
5652                         if (app.persistent) {
5653                             // We don't kill persistent processes.
5654                             continue;
5655                         }
5656                         if (app.removed) {
5657                             procs.add(app);
5658                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5659                             app.removed = true;
5660                             procs.add(app);
5661                         }
5662                     }
5663                 }
5664
5665                 final int N = procs.size();
5666                 for (int i = 0; i < N; i++) {
5667                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5668                 }
5669
5670                 mAllowLowerMemLevel = true;
5671
5672                 updateOomAdjLocked();
5673                 doLowMemReportIfNeededLocked(null);
5674             }
5675         } finally {
5676             Binder.restoreCallingIdentity(callingId);
5677         }
5678     }
5679
5680     /**
5681      * Kills all background processes, except those matching any of the
5682      * specified properties.
5683      *
5684      * @param minTargetSdk the target SDK version at or above which to preserve
5685      *                     processes, or {@code -1} to ignore the target SDK
5686      * @param maxProcState the process state at or below which to preserve
5687      *                     processes, or {@code -1} to ignore the process state
5688      */
5689     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5690         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5691                 != PackageManager.PERMISSION_GRANTED) {
5692             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5693                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5694                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5695             Slog.w(TAG, msg);
5696             throw new SecurityException(msg);
5697         }
5698
5699         final long callingId = Binder.clearCallingIdentity();
5700         try {
5701             synchronized (this) {
5702                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5703                 final int NP = mProcessNames.getMap().size();
5704                 for (int ip = 0; ip < NP; ip++) {
5705                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5706                     final int NA = apps.size();
5707                     for (int ia = 0; ia < NA; ia++) {
5708                         final ProcessRecord app = apps.valueAt(ia);
5709                         if (app.removed) {
5710                             procs.add(app);
5711                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5712                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5713                             app.removed = true;
5714                             procs.add(app);
5715                         }
5716                     }
5717                 }
5718
5719                 final int N = procs.size();
5720                 for (int i = 0; i < N; i++) {
5721                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5722                 }
5723             }
5724         } finally {
5725             Binder.restoreCallingIdentity(callingId);
5726         }
5727     }
5728
5729     @Override
5730     public void forceStopPackage(final String packageName, int userId) {
5731         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5732                 != PackageManager.PERMISSION_GRANTED) {
5733             String msg = "Permission Denial: forceStopPackage() from pid="
5734                     + Binder.getCallingPid()
5735                     + ", uid=" + Binder.getCallingUid()
5736                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5737             Slog.w(TAG, msg);
5738             throw new SecurityException(msg);
5739         }
5740         final int callingPid = Binder.getCallingPid();
5741         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5742                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5743         long callingId = Binder.clearCallingIdentity();
5744         try {
5745             IPackageManager pm = AppGlobals.getPackageManager();
5746             synchronized(this) {
5747                 int[] users = userId == UserHandle.USER_ALL
5748                         ? mUserController.getUsers() : new int[] { userId };
5749                 for (int user : users) {
5750                     int pkgUid = -1;
5751                     try {
5752                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5753                                 user);
5754                     } catch (RemoteException e) {
5755                     }
5756                     if (pkgUid == -1) {
5757                         Slog.w(TAG, "Invalid packageName: " + packageName);
5758                         continue;
5759                     }
5760                     try {
5761                         pm.setPackageStoppedState(packageName, true, user);
5762                     } catch (RemoteException e) {
5763                     } catch (IllegalArgumentException e) {
5764                         Slog.w(TAG, "Failed trying to unstop package "
5765                                 + packageName + ": " + e);
5766                     }
5767                     if (mUserController.isUserRunningLocked(user, 0)) {
5768                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5769                         finishForceStopPackageLocked(packageName, pkgUid);
5770                     }
5771                 }
5772             }
5773         } finally {
5774             Binder.restoreCallingIdentity(callingId);
5775         }
5776     }
5777
5778     @Override
5779     public void addPackageDependency(String packageName) {
5780         synchronized (this) {
5781             int callingPid = Binder.getCallingPid();
5782             if (callingPid == Process.myPid()) {
5783                 //  Yeah, um, no.
5784                 return;
5785             }
5786             ProcessRecord proc;
5787             synchronized (mPidsSelfLocked) {
5788                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5789             }
5790             if (proc != null) {
5791                 if (proc.pkgDeps == null) {
5792                     proc.pkgDeps = new ArraySet<String>(1);
5793                 }
5794                 proc.pkgDeps.add(packageName);
5795             }
5796         }
5797     }
5798
5799     /*
5800      * The pkg name and app id have to be specified.
5801      */
5802     @Override
5803     public void killApplication(String pkg, int appId, int userId, String reason) {
5804         if (pkg == null) {
5805             return;
5806         }
5807         // Make sure the uid is valid.
5808         if (appId < 0) {
5809             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5810             return;
5811         }
5812         int callerUid = Binder.getCallingUid();
5813         // Only the system server can kill an application
5814         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5815             // Post an aysnc message to kill the application
5816             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5817             msg.arg1 = appId;
5818             msg.arg2 = userId;
5819             Bundle bundle = new Bundle();
5820             bundle.putString("pkg", pkg);
5821             bundle.putString("reason", reason);
5822             msg.obj = bundle;
5823             mHandler.sendMessage(msg);
5824         } else {
5825             throw new SecurityException(callerUid + " cannot kill pkg: " +
5826                     pkg);
5827         }
5828     }
5829
5830     @Override
5831     public void closeSystemDialogs(String reason) {
5832         enforceNotIsolatedCaller("closeSystemDialogs");
5833
5834         final int pid = Binder.getCallingPid();
5835         final int uid = Binder.getCallingUid();
5836         final long origId = Binder.clearCallingIdentity();
5837         try {
5838             synchronized (this) {
5839                 // Only allow this from foreground processes, so that background
5840                 // applications can't abuse it to prevent system UI from being shown.
5841                 if (uid >= Process.FIRST_APPLICATION_UID) {
5842                     ProcessRecord proc;
5843                     synchronized (mPidsSelfLocked) {
5844                         proc = mPidsSelfLocked.get(pid);
5845                     }
5846                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5847                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5848                                 + " from background process " + proc);
5849                         return;
5850                     }
5851                 }
5852                 closeSystemDialogsLocked(reason);
5853             }
5854         } finally {
5855             Binder.restoreCallingIdentity(origId);
5856         }
5857     }
5858
5859     void closeSystemDialogsLocked(String reason) {
5860         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5861         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5862                 | Intent.FLAG_RECEIVER_FOREGROUND);
5863         if (reason != null) {
5864             intent.putExtra("reason", reason);
5865         }
5866         mWindowManager.closeSystemDialogs(reason);
5867
5868         mStackSupervisor.closeSystemDialogsLocked();
5869
5870         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5871                 AppOpsManager.OP_NONE, null, false, false,
5872                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5873     }
5874
5875     @Override
5876     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5877         enforceNotIsolatedCaller("getProcessMemoryInfo");
5878         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5879         for (int i=pids.length-1; i>=0; i--) {
5880             ProcessRecord proc;
5881             int oomAdj;
5882             synchronized (this) {
5883                 synchronized (mPidsSelfLocked) {
5884                     proc = mPidsSelfLocked.get(pids[i]);
5885                     oomAdj = proc != null ? proc.setAdj : 0;
5886                 }
5887             }
5888             infos[i] = new Debug.MemoryInfo();
5889             Debug.getMemoryInfo(pids[i], infos[i]);
5890             if (proc != null) {
5891                 synchronized (this) {
5892                     if (proc.thread != null && proc.setAdj == oomAdj) {
5893                         // Record this for posterity if the process has been stable.
5894                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5895                                 infos[i].getTotalUss(), false, proc.pkgList);
5896                     }
5897                 }
5898             }
5899         }
5900         return infos;
5901     }
5902
5903     @Override
5904     public long[] getProcessPss(int[] pids) {
5905         enforceNotIsolatedCaller("getProcessPss");
5906         long[] pss = new long[pids.length];
5907         for (int i=pids.length-1; i>=0; i--) {
5908             ProcessRecord proc;
5909             int oomAdj;
5910             synchronized (this) {
5911                 synchronized (mPidsSelfLocked) {
5912                     proc = mPidsSelfLocked.get(pids[i]);
5913                     oomAdj = proc != null ? proc.setAdj : 0;
5914                 }
5915             }
5916             long[] tmpUss = new long[1];
5917             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5918             if (proc != null) {
5919                 synchronized (this) {
5920                     if (proc.thread != null && proc.setAdj == oomAdj) {
5921                         // Record this for posterity if the process has been stable.
5922                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5923                     }
5924                 }
5925             }
5926         }
5927         return pss;
5928     }
5929
5930     @Override
5931     public void killApplicationProcess(String processName, int uid) {
5932         if (processName == null) {
5933             return;
5934         }
5935
5936         int callerUid = Binder.getCallingUid();
5937         // Only the system server can kill an application
5938         if (callerUid == Process.SYSTEM_UID) {
5939             synchronized (this) {
5940                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5941                 if (app != null && app.thread != null) {
5942                     try {
5943                         app.thread.scheduleSuicide();
5944                     } catch (RemoteException e) {
5945                         // If the other end already died, then our work here is done.
5946                     }
5947                 } else {
5948                     Slog.w(TAG, "Process/uid not found attempting kill of "
5949                             + processName + " / " + uid);
5950                 }
5951             }
5952         } else {
5953             throw new SecurityException(callerUid + " cannot kill app process: " +
5954                     processName);
5955         }
5956     }
5957
5958     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5959         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5960                 false, true, false, false, UserHandle.getUserId(uid), reason);
5961     }
5962
5963     private void finishForceStopPackageLocked(final String packageName, int uid) {
5964         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5965                 Uri.fromParts("package", packageName, null));
5966         if (!mProcessesReady) {
5967             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5968                     | Intent.FLAG_RECEIVER_FOREGROUND);
5969         }
5970         intent.putExtra(Intent.EXTRA_UID, uid);
5971         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5972         broadcastIntentLocked(null, null, intent,
5973                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5974                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5975     }
5976
5977
5978     private final boolean killPackageProcessesLocked(String packageName, int appId,
5979             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5980             boolean doit, boolean evenPersistent, String reason) {
5981         ArrayList<ProcessRecord> procs = new ArrayList<>();
5982
5983         // Remove all processes this package may have touched: all with the
5984         // same UID (except for the system or root user), and all whose name
5985         // matches the package name.
5986         final int NP = mProcessNames.getMap().size();
5987         for (int ip=0; ip<NP; ip++) {
5988             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5989             final int NA = apps.size();
5990             for (int ia=0; ia<NA; ia++) {
5991                 ProcessRecord app = apps.valueAt(ia);
5992                 if (app.persistent && !evenPersistent) {
5993                     // we don't kill persistent processes
5994                     continue;
5995                 }
5996                 if (app.removed) {
5997                     if (doit) {
5998                         procs.add(app);
5999                     }
6000                     continue;
6001                 }
6002
6003                 // Skip process if it doesn't meet our oom adj requirement.
6004                 if (app.setAdj < minOomAdj) {
6005                     continue;
6006                 }
6007
6008                 // If no package is specified, we call all processes under the
6009                 // give user id.
6010                 if (packageName == null) {
6011                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6012                         continue;
6013                     }
6014                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6015                         continue;
6016                     }
6017                 // Package has been specified, we want to hit all processes
6018                 // that match it.  We need to qualify this by the processes
6019                 // that are running under the specified app and user ID.
6020                 } else {
6021                     final boolean isDep = app.pkgDeps != null
6022                             && app.pkgDeps.contains(packageName);
6023                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6024                         continue;
6025                     }
6026                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6027                         continue;
6028                     }
6029                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6030                         continue;
6031                     }
6032                 }
6033
6034                 // Process has passed all conditions, kill it!
6035                 if (!doit) {
6036                     return true;
6037                 }
6038                 app.removed = true;
6039                 procs.add(app);
6040             }
6041         }
6042
6043         int N = procs.size();
6044         for (int i=0; i<N; i++) {
6045             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6046         }
6047         updateOomAdjLocked();
6048         return N > 0;
6049     }
6050
6051     private void cleanupDisabledPackageComponentsLocked(
6052             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6053
6054         Set<String> disabledClasses = null;
6055         boolean packageDisabled = false;
6056         IPackageManager pm = AppGlobals.getPackageManager();
6057
6058         if (changedClasses == null) {
6059             // Nothing changed...
6060             return;
6061         }
6062
6063         // Determine enable/disable state of the package and its components.
6064         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6065         for (int i = changedClasses.length - 1; i >= 0; i--) {
6066             final String changedClass = changedClasses[i];
6067
6068             if (changedClass.equals(packageName)) {
6069                 try {
6070                     // Entire package setting changed
6071                     enabled = pm.getApplicationEnabledSetting(packageName,
6072                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6073                 } catch (Exception e) {
6074                     // No such package/component; probably racing with uninstall.  In any
6075                     // event it means we have nothing further to do here.
6076                     return;
6077                 }
6078                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6079                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6080                 if (packageDisabled) {
6081                     // Entire package is disabled.
6082                     // No need to continue to check component states.
6083                     disabledClasses = null;
6084                     break;
6085                 }
6086             } else {
6087                 try {
6088                     enabled = pm.getComponentEnabledSetting(
6089                             new ComponentName(packageName, changedClass),
6090                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6091                 } catch (Exception e) {
6092                     // As above, probably racing with uninstall.
6093                     return;
6094                 }
6095                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6096                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6097                     if (disabledClasses == null) {
6098                         disabledClasses = new ArraySet<>(changedClasses.length);
6099                     }
6100                     disabledClasses.add(changedClass);
6101                 }
6102             }
6103         }
6104
6105         if (!packageDisabled && disabledClasses == null) {
6106             // Nothing to do here...
6107             return;
6108         }
6109
6110         // Clean-up disabled activities.
6111         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6112                 packageName, disabledClasses, true, false, userId) && mBooted) {
6113             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6114             mStackSupervisor.scheduleIdleLocked();
6115         }
6116
6117         // Clean-up disabled tasks
6118         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6119
6120         // Clean-up disabled services.
6121         mServices.bringDownDisabledPackageServicesLocked(
6122                 packageName, disabledClasses, userId, false, killProcess, true);
6123
6124         // Clean-up disabled providers.
6125         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6126         mProviderMap.collectPackageProvidersLocked(
6127                 packageName, disabledClasses, true, false, userId, providers);
6128         for (int i = providers.size() - 1; i >= 0; i--) {
6129             removeDyingProviderLocked(null, providers.get(i), true);
6130         }
6131
6132         // Clean-up disabled broadcast receivers.
6133         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6134             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6135                     packageName, disabledClasses, userId, true);
6136         }
6137
6138     }
6139
6140     final boolean clearBroadcastQueueForUserLocked(int userId) {
6141         boolean didSomething = false;
6142         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6143             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6144                     null, null, userId, true);
6145         }
6146         return didSomething;
6147     }
6148
6149     final boolean forceStopPackageLocked(String packageName, int appId,
6150             boolean callerWillRestart, boolean purgeCache, boolean doit,
6151             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6152         int i;
6153
6154         if (userId == UserHandle.USER_ALL && packageName == null) {
6155             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6156         }
6157
6158         if (appId < 0 && packageName != null) {
6159             try {
6160                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6161                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6162             } catch (RemoteException e) {
6163             }
6164         }
6165
6166         if (doit) {
6167             if (packageName != null) {
6168                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6169                         + " user=" + userId + ": " + reason);
6170             } else {
6171                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6172             }
6173
6174             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6175         }
6176
6177         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6178                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6179                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6180
6181         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6182                 packageName, null, doit, evenPersistent, userId)) {
6183             if (!doit) {
6184                 return true;
6185             }
6186             didSomething = true;
6187         }
6188
6189         if (mServices.bringDownDisabledPackageServicesLocked(
6190                 packageName, null, userId, evenPersistent, true, doit)) {
6191             if (!doit) {
6192                 return true;
6193             }
6194             didSomething = true;
6195         }
6196
6197         if (packageName == null) {
6198             // Remove all sticky broadcasts from this user.
6199             mStickyBroadcasts.remove(userId);
6200         }
6201
6202         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6203         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6204                 userId, providers)) {
6205             if (!doit) {
6206                 return true;
6207             }
6208             didSomething = true;
6209         }
6210         for (i = providers.size() - 1; i >= 0; i--) {
6211             removeDyingProviderLocked(null, providers.get(i), true);
6212         }
6213
6214         // Remove transient permissions granted from/to this package/user
6215         removeUriPermissionsForPackageLocked(packageName, userId, false);
6216
6217         if (doit) {
6218             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6219                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6220                         packageName, null, userId, doit);
6221             }
6222         }
6223
6224         if (packageName == null || uninstalling) {
6225             // Remove pending intents.  For now we only do this when force
6226             // stopping users, because we have some problems when doing this
6227             // for packages -- app widgets are not currently cleaned up for
6228             // such packages, so they can be left with bad pending intents.
6229             if (mIntentSenderRecords.size() > 0) {
6230                 Iterator<WeakReference<PendingIntentRecord>> it
6231                         = mIntentSenderRecords.values().iterator();
6232                 while (it.hasNext()) {
6233                     WeakReference<PendingIntentRecord> wpir = it.next();
6234                     if (wpir == null) {
6235                         it.remove();
6236                         continue;
6237                     }
6238                     PendingIntentRecord pir = wpir.get();
6239                     if (pir == null) {
6240                         it.remove();
6241                         continue;
6242                     }
6243                     if (packageName == null) {
6244                         // Stopping user, remove all objects for the user.
6245                         if (pir.key.userId != userId) {
6246                             // Not the same user, skip it.
6247                             continue;
6248                         }
6249                     } else {
6250                         if (UserHandle.getAppId(pir.uid) != appId) {
6251                             // Different app id, skip it.
6252                             continue;
6253                         }
6254                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6255                             // Different user, skip it.
6256                             continue;
6257                         }
6258                         if (!pir.key.packageName.equals(packageName)) {
6259                             // Different package, skip it.
6260                             continue;
6261                         }
6262                     }
6263                     if (!doit) {
6264                         return true;
6265                     }
6266                     didSomething = true;
6267                     it.remove();
6268                     pir.canceled = true;
6269                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6270                         pir.key.activity.pendingResults.remove(pir.ref);
6271                     }
6272                 }
6273             }
6274         }
6275
6276         if (doit) {
6277             if (purgeCache && packageName != null) {
6278                 AttributeCache ac = AttributeCache.instance();
6279                 if (ac != null) {
6280                     ac.removePackage(packageName);
6281                 }
6282             }
6283             if (mBooted) {
6284                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6285                 mStackSupervisor.scheduleIdleLocked();
6286             }
6287         }
6288
6289         return didSomething;
6290     }
6291
6292     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6293         return removeProcessNameLocked(name, uid, null);
6294     }
6295
6296     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6297             final ProcessRecord expecting) {
6298         ProcessRecord old = mProcessNames.get(name, uid);
6299         // Only actually remove when the currently recorded value matches the
6300         // record that we expected; if it doesn't match then we raced with a
6301         // newly created process and we don't want to destroy the new one.
6302         if ((expecting == null) || (old == expecting)) {
6303             mProcessNames.remove(name, uid);
6304         }
6305         if (old != null && old.uidRecord != null) {
6306             old.uidRecord.numProcs--;
6307             if (old.uidRecord.numProcs == 0) {
6308                 // No more processes using this uid, tell clients it is gone.
6309                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6310                         "No more processes in " + old.uidRecord);
6311                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6312                 mActiveUids.remove(uid);
6313                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6314             }
6315             old.uidRecord = null;
6316         }
6317         mIsolatedProcesses.remove(uid);
6318         return old;
6319     }
6320
6321     private final void addProcessNameLocked(ProcessRecord proc) {
6322         // We shouldn't already have a process under this name, but just in case we
6323         // need to clean up whatever may be there now.
6324         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6325         if (old == proc && proc.persistent) {
6326             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6327             Slog.w(TAG, "Re-adding persistent process " + proc);
6328         } else if (old != null) {
6329             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6330         }
6331         UidRecord uidRec = mActiveUids.get(proc.uid);
6332         if (uidRec == null) {
6333             uidRec = new UidRecord(proc.uid);
6334             // This is the first appearance of the uid, report it now!
6335             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6336                     "Creating new process uid: " + uidRec);
6337             mActiveUids.put(proc.uid, uidRec);
6338             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6339             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6340         }
6341         proc.uidRecord = uidRec;
6342
6343         // Reset render thread tid if it was already set, so new process can set it again.
6344         proc.renderThreadTid = 0;
6345         uidRec.numProcs++;
6346         mProcessNames.put(proc.processName, proc.uid, proc);
6347         if (proc.isolated) {
6348             mIsolatedProcesses.put(proc.uid, proc);
6349         }
6350     }
6351
6352     boolean removeProcessLocked(ProcessRecord app,
6353             boolean callerWillRestart, boolean allowRestart, String reason) {
6354         final String name = app.processName;
6355         final int uid = app.uid;
6356         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6357             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6358
6359         ProcessRecord old = mProcessNames.get(name, uid);
6360         if (old != app) {
6361             // This process is no longer active, so nothing to do.
6362             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6363             return false;
6364         }
6365         removeProcessNameLocked(name, uid);
6366         if (mHeavyWeightProcess == app) {
6367             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6368                     mHeavyWeightProcess.userId, 0));
6369             mHeavyWeightProcess = null;
6370         }
6371         boolean needRestart = false;
6372         if (app.pid > 0 && app.pid != MY_PID) {
6373             int pid = app.pid;
6374             synchronized (mPidsSelfLocked) {
6375                 mPidsSelfLocked.remove(pid);
6376                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6377             }
6378             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6379             if (app.isolated) {
6380                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6381             }
6382             boolean willRestart = false;
6383             if (app.persistent && !app.isolated) {
6384                 if (!callerWillRestart) {
6385                     willRestart = true;
6386                 } else {
6387                     needRestart = true;
6388                 }
6389             }
6390             app.kill(reason, true);
6391             handleAppDiedLocked(app, willRestart, allowRestart);
6392             if (willRestart) {
6393                 removeLruProcessLocked(app);
6394                 addAppLocked(app.info, false, null /* ABI override */);
6395             }
6396         } else {
6397             mRemovedProcesses.add(app);
6398         }
6399
6400         return needRestart;
6401     }
6402
6403     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6404         cleanupAppInLaunchingProvidersLocked(app, true);
6405         removeProcessLocked(app, false, true, "timeout publishing content providers");
6406     }
6407
6408     private final void processStartTimedOutLocked(ProcessRecord app) {
6409         final int pid = app.pid;
6410         boolean gone = false;
6411         synchronized (mPidsSelfLocked) {
6412             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6413             if (knownApp != null && knownApp.thread == null) {
6414                 mPidsSelfLocked.remove(pid);
6415                 gone = true;
6416             }
6417         }
6418
6419         if (gone) {
6420             Slog.w(TAG, "Process " + app + " failed to attach");
6421             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6422                     pid, app.uid, app.processName);
6423             removeProcessNameLocked(app.processName, app.uid);
6424             if (mHeavyWeightProcess == app) {
6425                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6426                         mHeavyWeightProcess.userId, 0));
6427                 mHeavyWeightProcess = null;
6428             }
6429             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6430             if (app.isolated) {
6431                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6432             }
6433             // Take care of any launching providers waiting for this process.
6434             cleanupAppInLaunchingProvidersLocked(app, true);
6435             // Take care of any services that are waiting for the process.
6436             mServices.processStartTimedOutLocked(app);
6437             app.kill("start timeout", true);
6438             removeLruProcessLocked(app);
6439             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6440                 Slog.w(TAG, "Unattached app died before backup, skipping");
6441                 try {
6442                     IBackupManager bm = IBackupManager.Stub.asInterface(
6443                             ServiceManager.getService(Context.BACKUP_SERVICE));
6444                     bm.agentDisconnected(app.info.packageName);
6445                 } catch (RemoteException e) {
6446                     // Can't happen; the backup manager is local
6447                 }
6448             }
6449             if (isPendingBroadcastProcessLocked(pid)) {
6450                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6451                 skipPendingBroadcastLocked(pid);
6452             }
6453         } else {
6454             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6455         }
6456     }
6457
6458     private final boolean attachApplicationLocked(IApplicationThread thread,
6459             int pid) {
6460
6461         // Find the application record that is being attached...  either via
6462         // the pid if we are running in multiple processes, or just pull the
6463         // next app record if we are emulating process with anonymous threads.
6464         ProcessRecord app;
6465         long startTime = SystemClock.uptimeMillis();
6466         if (pid != MY_PID && pid >= 0) {
6467             synchronized (mPidsSelfLocked) {
6468                 app = mPidsSelfLocked.get(pid);
6469             }
6470         } else {
6471             app = null;
6472         }
6473
6474         if (app == null) {
6475             Slog.w(TAG, "No pending application record for pid " + pid
6476                     + " (IApplicationThread " + thread + "); dropping process");
6477             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6478             if (pid > 0 && pid != MY_PID) {
6479                 Process.killProcessQuiet(pid);
6480                 //TODO: killProcessGroup(app.info.uid, pid);
6481             } else {
6482                 try {
6483                     thread.scheduleExit();
6484                 } catch (Exception e) {
6485                     // Ignore exceptions.
6486                 }
6487             }
6488             return false;
6489         }
6490
6491         // If this application record is still attached to a previous
6492         // process, clean it up now.
6493         if (app.thread != null) {
6494             handleAppDiedLocked(app, true, true);
6495         }
6496
6497         // Tell the process all about itself.
6498
6499         if (DEBUG_ALL) Slog.v(
6500                 TAG, "Binding process pid " + pid + " to record " + app);
6501
6502         final String processName = app.processName;
6503         try {
6504             AppDeathRecipient adr = new AppDeathRecipient(
6505                     app, pid, thread);
6506             thread.asBinder().linkToDeath(adr, 0);
6507             app.deathRecipient = adr;
6508         } catch (RemoteException e) {
6509             app.resetPackageList(mProcessStats);
6510             startProcessLocked(app, "link fail", processName);
6511             return false;
6512         }
6513
6514         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6515
6516         app.makeActive(thread, mProcessStats);
6517         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6518         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6519         app.forcingToForeground = null;
6520         updateProcessForegroundLocked(app, false, false);
6521         app.hasShownUi = false;
6522         app.debugging = false;
6523         app.cached = false;
6524         app.killedByAm = false;
6525
6526         // We carefully use the same state that PackageManager uses for
6527         // filtering, since we use this flag to decide if we need to install
6528         // providers when user is unlocked later
6529         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6530
6531         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6532
6533         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6534         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6535
6536         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6537             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6538             msg.obj = app;
6539             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6540         }
6541
6542         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6543         
6544         if (!normalMode) {
6545             Slog.i(TAG, "Launching preboot mode app: " + app);
6546         }
6547
6548         if (DEBUG_ALL) Slog.v(
6549             TAG, "New app record " + app
6550             + " thread=" + thread.asBinder() + " pid=" + pid);
6551         try {
6552             int testMode = IApplicationThread.DEBUG_OFF;
6553             if (mDebugApp != null && mDebugApp.equals(processName)) {
6554                 testMode = mWaitForDebugger
6555                     ? IApplicationThread.DEBUG_WAIT
6556                     : IApplicationThread.DEBUG_ON;
6557                 app.debugging = true;
6558                 if (mDebugTransient) {
6559                     mDebugApp = mOrigDebugApp;
6560                     mWaitForDebugger = mOrigWaitForDebugger;
6561                 }
6562             }
6563             String profileFile = app.instrumentationProfileFile;
6564             ParcelFileDescriptor profileFd = null;
6565             int samplingInterval = 0;
6566             boolean profileAutoStop = false;
6567             if (mProfileApp != null && mProfileApp.equals(processName)) {
6568                 mProfileProc = app;
6569                 profileFile = mProfileFile;
6570                 profileFd = mProfileFd;
6571                 samplingInterval = mSamplingInterval;
6572                 profileAutoStop = mAutoStopProfiler;
6573             }
6574             boolean enableTrackAllocation = false;
6575             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6576                 enableTrackAllocation = true;
6577                 mTrackAllocationApp = null;
6578             }
6579
6580             // If the app is being launched for restore or full backup, set it up specially
6581             boolean isRestrictedBackupMode = false;
6582             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6583                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6584                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6585                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6586                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6587             }
6588
6589             if (app.instrumentationClass != null) {
6590                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6591                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6592             }
6593             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6594                     + processName + " with config " + mConfiguration);
6595             ApplicationInfo appInfo = app.instrumentationInfo != null
6596                     ? app.instrumentationInfo : app.info;
6597             app.compat = compatibilityInfoForPackageLocked(appInfo);
6598             if (profileFd != null) {
6599                 profileFd = profileFd.dup();
6600             }
6601             ProfilerInfo profilerInfo = profileFile == null ? null
6602                 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6603             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6604             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6605                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6606                     app.instrumentationUiAutomationConnection, testMode,
6607                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6608                     isRestrictedBackupMode || !normalMode, app.persistent,
6609                     new Configuration(mConfiguration), app.compat,
6610                     getCommonServicesLocked(app.isolated),
6611                                    mCoreSettingsObserver.getCoreSettingsLocked());
6612             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6613             updateLruProcessLocked(app, false, null);
6614             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6615             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6616         } catch (Exception e) {
6617             // todo: Yikes!  What should we do?  For now we will try to
6618             // start another process, but that could easily get us in
6619             // an infinite loop of restarting processes...
6620             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6621
6622             app.resetPackageList(mProcessStats);
6623             app.unlinkDeathRecipient();
6624             startProcessLocked(app, "bind fail", processName);
6625             return false;
6626         }
6627
6628         // Remove this record from the list of starting applications.
6629         mPersistentStartingProcesses.remove(app);
6630         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6631                 "Attach application locked removing on hold: " + app);
6632         mProcessesOnHold.remove(app);
6633
6634         boolean badApp = false;
6635         boolean didSomething = false;
6636
6637         // See if the top visible activity is waiting to run in this process...
6638         if (normalMode) {
6639             try {
6640                 if (mStackSupervisor.attachApplicationLocked(app)) {
6641                     didSomething = true;
6642                 }
6643             } catch (Exception e) {
6644                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6645                 badApp = true;
6646             }
6647         }
6648
6649         // Find any services that should be running in this process...
6650         if (!badApp) {
6651             try {
6652                 didSomething |= mServices.attachApplicationLocked(app, processName);
6653                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6654             } catch (Exception e) {
6655                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6656                 badApp = true;
6657             }
6658         }
6659
6660         // Check if a next-broadcast receiver is in this process...
6661         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6662             try {
6663                 didSomething |= sendPendingBroadcastsLocked(app);
6664                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6665             } catch (Exception e) {
6666                 // If the app died trying to launch the receiver we declare it 'bad'
6667                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6668                 badApp = true;
6669             }
6670         }
6671
6672         // Check whether the next backup agent is in this process...
6673         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6674             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6675                     "New app is backup target, launching agent for " + app);
6676             notifyPackageUse(mBackupTarget.appInfo.packageName,
6677                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6678             try {
6679                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6680                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6681                         mBackupTarget.backupMode);
6682             } catch (Exception e) {
6683                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6684                 badApp = true;
6685             }
6686         }
6687
6688         if (badApp) {
6689             app.kill("error during init", true);
6690             handleAppDiedLocked(app, false, true);
6691             return false;
6692         }
6693
6694         if (!didSomething) {
6695             updateOomAdjLocked();
6696             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6697         }
6698
6699         return true;
6700     }
6701
6702     @Override
6703     public final void attachApplication(IApplicationThread thread) {
6704         synchronized (this) {
6705             int callingPid = Binder.getCallingPid();
6706             final long origId = Binder.clearCallingIdentity();
6707             attachApplicationLocked(thread, callingPid);
6708             Binder.restoreCallingIdentity(origId);
6709         }
6710     }
6711
6712     @Override
6713     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6714         final long origId = Binder.clearCallingIdentity();
6715         synchronized (this) {
6716             ActivityStack stack = ActivityRecord.getStackLocked(token);
6717             if (stack != null) {
6718                 ActivityRecord r =
6719                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6720                 if (stopProfiling) {
6721                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6722                         try {
6723                             mProfileFd.close();
6724                         } catch (IOException e) {
6725                         }
6726                         clearProfilerLocked();
6727                     }
6728                 }
6729             }
6730         }
6731         Binder.restoreCallingIdentity(origId);
6732     }
6733
6734     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6735         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6736                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6737     }
6738
6739     void enableScreenAfterBoot() {
6740         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6741                 SystemClock.uptimeMillis());
6742         mWindowManager.enableScreenAfterBoot();
6743
6744         synchronized (this) {
6745             updateEventDispatchingLocked();
6746         }
6747     }
6748
6749     @Override
6750     public void showBootMessage(final CharSequence msg, final boolean always) {
6751         if (Binder.getCallingUid() != Process.myUid()) {
6752             throw new SecurityException();
6753         }
6754         mWindowManager.showBootMessage(msg, always);
6755     }
6756
6757     @Override
6758     public void keyguardWaitingForActivityDrawn() {
6759         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6760         final long token = Binder.clearCallingIdentity();
6761         try {
6762             synchronized (this) {
6763                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6764                 mWindowManager.keyguardWaitingForActivityDrawn();
6765                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6766                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6767                     updateSleepIfNeededLocked();
6768                 }
6769             }
6770         } finally {
6771             Binder.restoreCallingIdentity(token);
6772         }
6773     }
6774
6775     @Override
6776     public void keyguardGoingAway(int flags) {
6777         enforceNotIsolatedCaller("keyguardGoingAway");
6778         final long token = Binder.clearCallingIdentity();
6779         try {
6780             synchronized (this) {
6781                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6782                 mWindowManager.keyguardGoingAway(flags);
6783                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6784                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6785                     updateSleepIfNeededLocked();
6786
6787                     // Some stack visibility might change (e.g. docked stack)
6788                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6789                 }
6790             }
6791         } finally {
6792             Binder.restoreCallingIdentity(token);
6793         }
6794     }
6795
6796     final void finishBooting() {
6797         synchronized (this) {
6798             if (!mBootAnimationComplete) {
6799                 mCallFinishBooting = true;
6800                 return;
6801             }
6802             mCallFinishBooting = false;
6803         }
6804
6805         ArraySet<String> completedIsas = new ArraySet<String>();
6806         for (String abi : Build.SUPPORTED_ABIS) {
6807             Process.establishZygoteConnectionForAbi(abi);
6808             final String instructionSet = VMRuntime.getInstructionSet(abi);
6809             if (!completedIsas.contains(instructionSet)) {
6810                 try {
6811                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6812                 } catch (InstallerException e) {
6813                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6814                             e.getMessage() +")");
6815                 }
6816                 completedIsas.add(instructionSet);
6817             }
6818         }
6819
6820         IntentFilter pkgFilter = new IntentFilter();
6821         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6822         pkgFilter.addDataScheme("package");
6823         mContext.registerReceiver(new BroadcastReceiver() {
6824             @Override
6825             public void onReceive(Context context, Intent intent) {
6826                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6827                 if (pkgs != null) {
6828                     for (String pkg : pkgs) {
6829                         synchronized (ActivityManagerService.this) {
6830                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6831                                     0, "query restart")) {
6832                                 setResultCode(Activity.RESULT_OK);
6833                                 return;
6834                             }
6835                         }
6836                     }
6837                 }
6838             }
6839         }, pkgFilter);
6840
6841         IntentFilter dumpheapFilter = new IntentFilter();
6842         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6843         mContext.registerReceiver(new BroadcastReceiver() {
6844             @Override
6845             public void onReceive(Context context, Intent intent) {
6846                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6847                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6848                 } else {
6849                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6850                 }
6851             }
6852         }, dumpheapFilter);
6853
6854         // Let system services know.
6855         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6856
6857         synchronized (this) {
6858             // Ensure that any processes we had put on hold are now started
6859             // up.
6860             final int NP = mProcessesOnHold.size();
6861             if (NP > 0) {
6862                 ArrayList<ProcessRecord> procs =
6863                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6864                 for (int ip=0; ip<NP; ip++) {
6865                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6866                             + procs.get(ip));
6867                     startProcessLocked(procs.get(ip), "on-hold", null);
6868                 }
6869             }
6870
6871             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6872                 // Start looking for apps that are abusing wake locks.
6873                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6874                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6875                 // Tell anyone interested that we are done booting!
6876                 SystemProperties.set("sys.boot_completed", "1");
6877
6878                 // And trigger dev.bootcomplete if we are not showing encryption progress
6879                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6880                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6881                     SystemProperties.set("dev.bootcomplete", "1");
6882                 }
6883                 mUserController.sendBootCompletedLocked(
6884                         new IIntentReceiver.Stub() {
6885                             @Override
6886                             public void performReceive(Intent intent, int resultCode,
6887                                     String data, Bundle extras, boolean ordered,
6888                                     boolean sticky, int sendingUser) {
6889                                 synchronized (ActivityManagerService.this) {
6890                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6891                                             true, false);
6892                                 }
6893                             }
6894                         });
6895                 scheduleStartProfilesLocked();
6896             }
6897         }
6898     }
6899
6900     @Override
6901     public void bootAnimationComplete() {
6902         final boolean callFinishBooting;
6903         synchronized (this) {
6904             callFinishBooting = mCallFinishBooting;
6905             mBootAnimationComplete = true;
6906         }
6907         if (callFinishBooting) {
6908             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6909             finishBooting();
6910             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6911         }
6912     }
6913
6914     final void ensureBootCompleted() {
6915         boolean booting;
6916         boolean enableScreen;
6917         synchronized (this) {
6918             booting = mBooting;
6919             mBooting = false;
6920             enableScreen = !mBooted;
6921             mBooted = true;
6922         }
6923
6924         if (booting) {
6925             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6926             finishBooting();
6927             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6928         }
6929
6930         if (enableScreen) {
6931             enableScreenAfterBoot();
6932         }
6933     }
6934
6935     @Override
6936     public final void activityResumed(IBinder token) {
6937         final long origId = Binder.clearCallingIdentity();
6938         synchronized(this) {
6939             ActivityStack stack = ActivityRecord.getStackLocked(token);
6940             if (stack != null) {
6941                 stack.activityResumedLocked(token);
6942             }
6943         }
6944         Binder.restoreCallingIdentity(origId);
6945     }
6946
6947     @Override
6948     public final void activityPaused(IBinder token) {
6949         final long origId = Binder.clearCallingIdentity();
6950         synchronized(this) {
6951             ActivityStack stack = ActivityRecord.getStackLocked(token);
6952             if (stack != null) {
6953                 stack.activityPausedLocked(token, false);
6954             }
6955         }
6956         Binder.restoreCallingIdentity(origId);
6957     }
6958
6959     @Override
6960     public final void activityStopped(IBinder token, Bundle icicle,
6961             PersistableBundle persistentState, CharSequence description) {
6962         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6963
6964         // Refuse possible leaked file descriptors
6965         if (icicle != null && icicle.hasFileDescriptors()) {
6966             throw new IllegalArgumentException("File descriptors passed in Bundle");
6967         }
6968
6969         final long origId = Binder.clearCallingIdentity();
6970
6971         synchronized (this) {
6972             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6973             if (r != null) {
6974                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6975             }
6976         }
6977
6978         trimApplications();
6979
6980         Binder.restoreCallingIdentity(origId);
6981     }
6982
6983     @Override
6984     public final void activityDestroyed(IBinder token) {
6985         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6986         synchronized (this) {
6987             ActivityStack stack = ActivityRecord.getStackLocked(token);
6988             if (stack != null) {
6989                 stack.activityDestroyedLocked(token, "activityDestroyed");
6990             }
6991         }
6992     }
6993
6994     @Override
6995     public final void activityRelaunched(IBinder token) {
6996         final long origId = Binder.clearCallingIdentity();
6997         synchronized (this) {
6998             mStackSupervisor.activityRelaunchedLocked(token);
6999         }
7000         Binder.restoreCallingIdentity(origId);
7001     }
7002
7003     @Override
7004     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7005             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7006         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7007                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7008         synchronized (this) {
7009             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7010             if (record == null) {
7011                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7012                         + "found for: " + token);
7013             }
7014             record.setSizeConfigurations(horizontalSizeConfiguration,
7015                     verticalSizeConfigurations, smallestSizeConfigurations);
7016         }
7017     }
7018
7019     @Override
7020     public final void backgroundResourcesReleased(IBinder token) {
7021         final long origId = Binder.clearCallingIdentity();
7022         try {
7023             synchronized (this) {
7024                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7025                 if (stack != null) {
7026                     stack.backgroundResourcesReleased();
7027                 }
7028             }
7029         } finally {
7030             Binder.restoreCallingIdentity(origId);
7031         }
7032     }
7033
7034     @Override
7035     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7036         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7037     }
7038
7039     @Override
7040     public final void notifyEnterAnimationComplete(IBinder token) {
7041         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7042     }
7043
7044     @Override
7045     public String getCallingPackage(IBinder token) {
7046         synchronized (this) {
7047             ActivityRecord r = getCallingRecordLocked(token);
7048             return r != null ? r.info.packageName : null;
7049         }
7050     }
7051
7052     @Override
7053     public ComponentName getCallingActivity(IBinder token) {
7054         synchronized (this) {
7055             ActivityRecord r = getCallingRecordLocked(token);
7056             return r != null ? r.intent.getComponent() : null;
7057         }
7058     }
7059
7060     private ActivityRecord getCallingRecordLocked(IBinder token) {
7061         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7062         if (r == null) {
7063             return null;
7064         }
7065         return r.resultTo;
7066     }
7067
7068     @Override
7069     public ComponentName getActivityClassForToken(IBinder token) {
7070         synchronized(this) {
7071             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7072             if (r == null) {
7073                 return null;
7074             }
7075             return r.intent.getComponent();
7076         }
7077     }
7078
7079     @Override
7080     public String getPackageForToken(IBinder token) {
7081         synchronized(this) {
7082             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7083             if (r == null) {
7084                 return null;
7085             }
7086             return r.packageName;
7087         }
7088     }
7089
7090     @Override
7091     public boolean isRootVoiceInteraction(IBinder token) {
7092         synchronized(this) {
7093             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7094             if (r == null) {
7095                 return false;
7096             }
7097             return r.rootVoiceInteraction;
7098         }
7099     }
7100
7101     @Override
7102     public IIntentSender getIntentSender(int type,
7103             String packageName, IBinder token, String resultWho,
7104             int requestCode, Intent[] intents, String[] resolvedTypes,
7105             int flags, Bundle bOptions, int userId) {
7106         enforceNotIsolatedCaller("getIntentSender");
7107         // Refuse possible leaked file descriptors
7108         if (intents != null) {
7109             if (intents.length < 1) {
7110                 throw new IllegalArgumentException("Intents array length must be >= 1");
7111             }
7112             for (int i=0; i<intents.length; i++) {
7113                 Intent intent = intents[i];
7114                 if (intent != null) {
7115                     if (intent.hasFileDescriptors()) {
7116                         throw new IllegalArgumentException("File descriptors passed in Intent");
7117                     }
7118                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7119                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7120                         throw new IllegalArgumentException(
7121                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7122                     }
7123                     intents[i] = new Intent(intent);
7124                 }
7125             }
7126             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7127                 throw new IllegalArgumentException(
7128                         "Intent array length does not match resolvedTypes length");
7129             }
7130         }
7131         if (bOptions != null) {
7132             if (bOptions.hasFileDescriptors()) {
7133                 throw new IllegalArgumentException("File descriptors passed in options");
7134             }
7135         }
7136
7137         synchronized(this) {
7138             int callingUid = Binder.getCallingUid();
7139             int origUserId = userId;
7140             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7141                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7142                     ALLOW_NON_FULL, "getIntentSender", null);
7143             if (origUserId == UserHandle.USER_CURRENT) {
7144                 // We don't want to evaluate this until the pending intent is
7145                 // actually executed.  However, we do want to always do the
7146                 // security checking for it above.
7147                 userId = UserHandle.USER_CURRENT;
7148             }
7149             try {
7150                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7151                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7152                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7153                     if (!UserHandle.isSameApp(callingUid, uid)) {
7154                         String msg = "Permission Denial: getIntentSender() from pid="
7155                             + Binder.getCallingPid()
7156                             + ", uid=" + Binder.getCallingUid()
7157                             + ", (need uid=" + uid + ")"
7158                             + " is not allowed to send as package " + packageName;
7159                         Slog.w(TAG, msg);
7160                         throw new SecurityException(msg);
7161                     }
7162                 }
7163
7164                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7165                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7166
7167             } catch (RemoteException e) {
7168                 throw new SecurityException(e);
7169             }
7170         }
7171     }
7172
7173     IIntentSender getIntentSenderLocked(int type, String packageName,
7174             int callingUid, int userId, IBinder token, String resultWho,
7175             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7176             Bundle bOptions) {
7177         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7178         ActivityRecord activity = null;
7179         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7180             activity = ActivityRecord.isInStackLocked(token);
7181             if (activity == null) {
7182                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7183                 return null;
7184             }
7185             if (activity.finishing) {
7186                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7187                 return null;
7188             }
7189         }
7190
7191         // We're going to be splicing together extras before sending, so we're
7192         // okay poking into any contained extras.
7193         if (intents != null) {
7194             for (int i = 0; i < intents.length; i++) {
7195                 intents[i].setDefusable(true);
7196             }
7197         }
7198         Bundle.setDefusable(bOptions, true);
7199
7200         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7201         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7202         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7203         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7204                 |PendingIntent.FLAG_UPDATE_CURRENT);
7205
7206         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7207                 type, packageName, activity, resultWho,
7208                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7209         WeakReference<PendingIntentRecord> ref;
7210         ref = mIntentSenderRecords.get(key);
7211         PendingIntentRecord rec = ref != null ? ref.get() : null;
7212         if (rec != null) {
7213             if (!cancelCurrent) {
7214                 if (updateCurrent) {
7215                     if (rec.key.requestIntent != null) {
7216                         rec.key.requestIntent.replaceExtras(intents != null ?
7217                                 intents[intents.length - 1] : null);
7218                     }
7219                     if (intents != null) {
7220                         intents[intents.length-1] = rec.key.requestIntent;
7221                         rec.key.allIntents = intents;
7222                         rec.key.allResolvedTypes = resolvedTypes;
7223                     } else {
7224                         rec.key.allIntents = null;
7225                         rec.key.allResolvedTypes = null;
7226                     }
7227                 }
7228                 return rec;
7229             }
7230             rec.canceled = true;
7231             mIntentSenderRecords.remove(key);
7232         }
7233         if (noCreate) {
7234             return rec;
7235         }
7236         rec = new PendingIntentRecord(this, key, callingUid);
7237         mIntentSenderRecords.put(key, rec.ref);
7238         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7239             if (activity.pendingResults == null) {
7240                 activity.pendingResults
7241                         = new HashSet<WeakReference<PendingIntentRecord>>();
7242             }
7243             activity.pendingResults.add(rec.ref);
7244         }
7245         return rec;
7246     }
7247
7248     @Override
7249     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7250             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7251         if (target instanceof PendingIntentRecord) {
7252             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7253                     finishedReceiver, requiredPermission, options);
7254         } else {
7255             if (intent == null) {
7256                 // Weird case: someone has given us their own custom IIntentSender, and now
7257                 // they have someone else trying to send to it but of course this isn't
7258                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7259                 // supplying an Intent... but we never want to dispatch a null Intent to
7260                 // a receiver, so um...  let's make something up.
7261                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7262                 intent = new Intent(Intent.ACTION_MAIN);
7263             }
7264             try {
7265                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7266             } catch (RemoteException e) {
7267             }
7268             // Platform code can rely on getting a result back when the send is done, but if
7269             // this intent sender is from outside of the system we can't rely on it doing that.
7270             // So instead we don't give it the result receiver, and instead just directly
7271             // report the finish immediately.
7272             if (finishedReceiver != null) {
7273                 try {
7274                     finishedReceiver.performReceive(intent, 0,
7275                             null, null, false, false, UserHandle.getCallingUserId());
7276                 } catch (RemoteException e) {
7277                 }
7278             }
7279             return 0;
7280         }
7281     }
7282
7283     /**
7284      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7285      *
7286      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7287      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7288      */
7289     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7290         if (DEBUG_WHITELISTS) {
7291             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7292                     + targetUid + ", " + duration + ")");
7293         }
7294         synchronized (mPidsSelfLocked) {
7295             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7296             if (pr == null) {
7297                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7298                 return;
7299             }
7300             if (!pr.whitelistManager) {
7301                 if (DEBUG_WHITELISTS) {
7302                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7303                             + callerPid + " is not allowed");
7304                 }
7305                 return;
7306             }
7307         }
7308
7309         final long token = Binder.clearCallingIdentity();
7310         try {
7311             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7312                     true, "pe from uid:" + callerUid);
7313         } finally {
7314             Binder.restoreCallingIdentity(token);
7315         }
7316     }
7317
7318     @Override
7319     public void cancelIntentSender(IIntentSender sender) {
7320         if (!(sender instanceof PendingIntentRecord)) {
7321             return;
7322         }
7323         synchronized(this) {
7324             PendingIntentRecord rec = (PendingIntentRecord)sender;
7325             try {
7326                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7327                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7328                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7329                     String msg = "Permission Denial: cancelIntentSender() from pid="
7330                         + Binder.getCallingPid()
7331                         + ", uid=" + Binder.getCallingUid()
7332                         + " is not allowed to cancel packges "
7333                         + rec.key.packageName;
7334                     Slog.w(TAG, msg);
7335                     throw new SecurityException(msg);
7336                 }
7337             } catch (RemoteException e) {
7338                 throw new SecurityException(e);
7339             }
7340             cancelIntentSenderLocked(rec, true);
7341         }
7342     }
7343
7344     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7345         rec.canceled = true;
7346         mIntentSenderRecords.remove(rec.key);
7347         if (cleanActivity && rec.key.activity != null) {
7348             rec.key.activity.pendingResults.remove(rec.ref);
7349         }
7350     }
7351
7352     @Override
7353     public String getPackageForIntentSender(IIntentSender pendingResult) {
7354         if (!(pendingResult instanceof PendingIntentRecord)) {
7355             return null;
7356         }
7357         try {
7358             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7359             return res.key.packageName;
7360         } catch (ClassCastException e) {
7361         }
7362         return null;
7363     }
7364
7365     @Override
7366     public int getUidForIntentSender(IIntentSender sender) {
7367         if (sender instanceof PendingIntentRecord) {
7368             try {
7369                 PendingIntentRecord res = (PendingIntentRecord)sender;
7370                 return res.uid;
7371             } catch (ClassCastException e) {
7372             }
7373         }
7374         return -1;
7375     }
7376
7377     @Override
7378     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7379         if (!(pendingResult instanceof PendingIntentRecord)) {
7380             return false;
7381         }
7382         try {
7383             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7384             if (res.key.allIntents == null) {
7385                 return false;
7386             }
7387             for (int i=0; i<res.key.allIntents.length; i++) {
7388                 Intent intent = res.key.allIntents[i];
7389                 if (intent.getPackage() != null && intent.getComponent() != null) {
7390                     return false;
7391                 }
7392             }
7393             return true;
7394         } catch (ClassCastException e) {
7395         }
7396         return false;
7397     }
7398
7399     @Override
7400     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7401         if (!(pendingResult instanceof PendingIntentRecord)) {
7402             return false;
7403         }
7404         try {
7405             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7406             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7407                 return true;
7408             }
7409             return false;
7410         } catch (ClassCastException e) {
7411         }
7412         return false;
7413     }
7414
7415     @Override
7416     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7417         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7418                 "getIntentForIntentSender()");
7419         if (!(pendingResult instanceof PendingIntentRecord)) {
7420             return null;
7421         }
7422         try {
7423             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7424             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7425         } catch (ClassCastException e) {
7426         }
7427         return null;
7428     }
7429
7430     @Override
7431     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7432         if (!(pendingResult instanceof PendingIntentRecord)) {
7433             return null;
7434         }
7435         try {
7436             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7437             synchronized (this) {
7438                 return getTagForIntentSenderLocked(res, prefix);
7439             }
7440         } catch (ClassCastException e) {
7441         }
7442         return null;
7443     }
7444
7445     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7446         final Intent intent = res.key.requestIntent;
7447         if (intent != null) {
7448             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7449                     || res.lastTagPrefix.equals(prefix))) {
7450                 return res.lastTag;
7451             }
7452             res.lastTagPrefix = prefix;
7453             final StringBuilder sb = new StringBuilder(128);
7454             if (prefix != null) {
7455                 sb.append(prefix);
7456             }
7457             if (intent.getAction() != null) {
7458                 sb.append(intent.getAction());
7459             } else if (intent.getComponent() != null) {
7460                 intent.getComponent().appendShortString(sb);
7461             } else {
7462                 sb.append("?");
7463             }
7464             return res.lastTag = sb.toString();
7465         }
7466         return null;
7467     }
7468
7469     @Override
7470     public void setProcessLimit(int max) {
7471         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7472                 "setProcessLimit()");
7473         synchronized (this) {
7474             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7475             mProcessLimitOverride = max;
7476         }
7477         trimApplications();
7478     }
7479
7480     @Override
7481     public int getProcessLimit() {
7482         synchronized (this) {
7483             return mProcessLimitOverride;
7484         }
7485     }
7486
7487     void foregroundTokenDied(ForegroundToken token) {
7488         synchronized (ActivityManagerService.this) {
7489             synchronized (mPidsSelfLocked) {
7490                 ForegroundToken cur
7491                     = mForegroundProcesses.get(token.pid);
7492                 if (cur != token) {
7493                     return;
7494                 }
7495                 mForegroundProcesses.remove(token.pid);
7496                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7497                 if (pr == null) {
7498                     return;
7499                 }
7500                 pr.forcingToForeground = null;
7501                 updateProcessForegroundLocked(pr, false, false);
7502             }
7503             updateOomAdjLocked();
7504         }
7505     }
7506
7507     @Override
7508     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7509         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7510                 "setProcessForeground()");
7511         synchronized(this) {
7512             boolean changed = false;
7513
7514             synchronized (mPidsSelfLocked) {
7515                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7516                 if (pr == null && isForeground) {
7517                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7518                     return;
7519                 }
7520                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7521                 if (oldToken != null) {
7522                     oldToken.token.unlinkToDeath(oldToken, 0);
7523                     mForegroundProcesses.remove(pid);
7524                     if (pr != null) {
7525                         pr.forcingToForeground = null;
7526                     }
7527                     changed = true;
7528                 }
7529                 if (isForeground && token != null) {
7530                     ForegroundToken newToken = new ForegroundToken() {
7531                         @Override
7532                         public void binderDied() {
7533                             foregroundTokenDied(this);
7534                         }
7535                     };
7536                     newToken.pid = pid;
7537                     newToken.token = token;
7538                     try {
7539                         token.linkToDeath(newToken, 0);
7540                         mForegroundProcesses.put(pid, newToken);
7541                         pr.forcingToForeground = token;
7542                         changed = true;
7543                     } catch (RemoteException e) {
7544                         // If the process died while doing this, we will later
7545                         // do the cleanup with the process death link.
7546                     }
7547                 }
7548             }
7549
7550             if (changed) {
7551                 updateOomAdjLocked();
7552             }
7553         }
7554     }
7555
7556     @Override
7557     public boolean isAppForeground(int uid) throws RemoteException {
7558         synchronized (this) {
7559             UidRecord uidRec = mActiveUids.get(uid);
7560             if (uidRec == null || uidRec.idle) {
7561                 return false;
7562             }
7563             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7564         }
7565     }
7566
7567     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7568     // be guarded by permission checking.
7569     int getUidState(int uid) {
7570         synchronized (this) {
7571             UidRecord uidRec = mActiveUids.get(uid);
7572             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7573         }
7574     }
7575
7576     @Override
7577     public boolean isInMultiWindowMode(IBinder token) {
7578         final long origId = Binder.clearCallingIdentity();
7579         try {
7580             synchronized(this) {
7581                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7582                 if (r == null) {
7583                     return false;
7584                 }
7585                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7586                 return !r.task.mFullscreen;
7587             }
7588         } finally {
7589             Binder.restoreCallingIdentity(origId);
7590         }
7591     }
7592
7593     @Override
7594     public boolean isInPictureInPictureMode(IBinder token) {
7595         final long origId = Binder.clearCallingIdentity();
7596         try {
7597             synchronized(this) {
7598                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7599                 if (stack == null) {
7600                     return false;
7601                 }
7602                 return stack.mStackId == PINNED_STACK_ID;
7603             }
7604         } finally {
7605             Binder.restoreCallingIdentity(origId);
7606         }
7607     }
7608
7609     @Override
7610     public void enterPictureInPictureMode(IBinder token) {
7611         final long origId = Binder.clearCallingIdentity();
7612         try {
7613             synchronized(this) {
7614                 if (!mSupportsPictureInPicture) {
7615                     throw new IllegalStateException("enterPictureInPictureMode: "
7616                             + "Device doesn't support picture-in-picture mode.");
7617                 }
7618
7619                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7620
7621                 if (r == null) {
7622                     throw new IllegalStateException("enterPictureInPictureMode: "
7623                             + "Can't find activity for token=" + token);
7624                 }
7625
7626                 if (!r.supportsPictureInPicture()) {
7627                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7628                             + "Picture-In-Picture not supported for r=" + r);
7629                 }
7630
7631                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7632                 // current bounds.
7633                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7634                 final Rect bounds = (pinnedStack != null)
7635                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7636
7637                 mStackSupervisor.moveActivityToPinnedStackLocked(
7638                         r, "enterPictureInPictureMode", bounds);
7639             }
7640         } finally {
7641             Binder.restoreCallingIdentity(origId);
7642         }
7643     }
7644
7645     // =========================================================
7646     // PROCESS INFO
7647     // =========================================================
7648
7649     static class ProcessInfoService extends IProcessInfoService.Stub {
7650         final ActivityManagerService mActivityManagerService;
7651         ProcessInfoService(ActivityManagerService activityManagerService) {
7652             mActivityManagerService = activityManagerService;
7653         }
7654
7655         @Override
7656         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7657             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7658                     /*in*/ pids, /*out*/ states, null);
7659         }
7660
7661         @Override
7662         public void getProcessStatesAndOomScoresFromPids(
7663                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7664             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7665                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7666         }
7667     }
7668
7669     /**
7670      * For each PID in the given input array, write the current process state
7671      * for that process into the states array, or -1 to indicate that no
7672      * process with the given PID exists. If scores array is provided, write
7673      * the oom score for the process into the scores array, with INVALID_ADJ
7674      * indicating the PID doesn't exist.
7675      */
7676     public void getProcessStatesAndOomScoresForPIDs(
7677             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7678         if (scores != null) {
7679             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7680                     "getProcessStatesAndOomScoresForPIDs()");
7681         }
7682
7683         if (pids == null) {
7684             throw new NullPointerException("pids");
7685         } else if (states == null) {
7686             throw new NullPointerException("states");
7687         } else if (pids.length != states.length) {
7688             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7689         } else if (scores != null && pids.length != scores.length) {
7690             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7691         }
7692
7693         synchronized (mPidsSelfLocked) {
7694             for (int i = 0; i < pids.length; i++) {
7695                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7696                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7697                         pr.curProcState;
7698                 if (scores != null) {
7699                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7700                 }
7701             }
7702         }
7703     }
7704
7705     // =========================================================
7706     // PERMISSIONS
7707     // =========================================================
7708
7709     static class PermissionController extends IPermissionController.Stub {
7710         ActivityManagerService mActivityManagerService;
7711         PermissionController(ActivityManagerService activityManagerService) {
7712             mActivityManagerService = activityManagerService;
7713         }
7714
7715         @Override
7716         public boolean checkPermission(String permission, int pid, int uid) {
7717             return mActivityManagerService.checkPermission(permission, pid,
7718                     uid) == PackageManager.PERMISSION_GRANTED;
7719         }
7720
7721         @Override
7722         public String[] getPackagesForUid(int uid) {
7723             return mActivityManagerService.mContext.getPackageManager()
7724                     .getPackagesForUid(uid);
7725         }
7726
7727         @Override
7728         public boolean isRuntimePermission(String permission) {
7729             try {
7730                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7731                         .getPermissionInfo(permission, 0);
7732                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7733             } catch (NameNotFoundException nnfe) {
7734                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7735             }
7736             return false;
7737         }
7738     }
7739
7740     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7741         @Override
7742         public int checkComponentPermission(String permission, int pid, int uid,
7743                 int owningUid, boolean exported) {
7744             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7745                     owningUid, exported);
7746         }
7747
7748         @Override
7749         public Object getAMSLock() {
7750             return ActivityManagerService.this;
7751         }
7752     }
7753
7754     /**
7755      * This can be called with or without the global lock held.
7756      */
7757     int checkComponentPermission(String permission, int pid, int uid,
7758             int owningUid, boolean exported) {
7759         if (pid == MY_PID) {
7760             return PackageManager.PERMISSION_GRANTED;
7761         }
7762         return ActivityManager.checkComponentPermission(permission, uid,
7763                 owningUid, exported);
7764     }
7765
7766     /**
7767      * As the only public entry point for permissions checking, this method
7768      * can enforce the semantic that requesting a check on a null global
7769      * permission is automatically denied.  (Internally a null permission
7770      * string is used when calling {@link #checkComponentPermission} in cases
7771      * when only uid-based security is needed.)
7772      *
7773      * This can be called with or without the global lock held.
7774      */
7775     @Override
7776     public int checkPermission(String permission, int pid, int uid) {
7777         if (permission == null) {
7778             return PackageManager.PERMISSION_DENIED;
7779         }
7780         return checkComponentPermission(permission, pid, uid, -1, true);
7781     }
7782
7783     @Override
7784     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7785         if (permission == null) {
7786             return PackageManager.PERMISSION_DENIED;
7787         }
7788
7789         // We might be performing an operation on behalf of an indirect binder
7790         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7791         // client identity accordingly before proceeding.
7792         Identity tlsIdentity = sCallerIdentity.get();
7793         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7794             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7795                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7796             uid = tlsIdentity.uid;
7797             pid = tlsIdentity.pid;
7798         }
7799
7800         return checkComponentPermission(permission, pid, uid, -1, true);
7801     }
7802
7803     /**
7804      * Binder IPC calls go through the public entry point.
7805      * This can be called with or without the global lock held.
7806      */
7807     int checkCallingPermission(String permission) {
7808         return checkPermission(permission,
7809                 Binder.getCallingPid(),
7810                 UserHandle.getAppId(Binder.getCallingUid()));
7811     }
7812
7813     /**
7814      * This can be called with or without the global lock held.
7815      */
7816     void enforceCallingPermission(String permission, String func) {
7817         if (checkCallingPermission(permission)
7818                 == PackageManager.PERMISSION_GRANTED) {
7819             return;
7820         }
7821
7822         String msg = "Permission Denial: " + func + " from pid="
7823                 + Binder.getCallingPid()
7824                 + ", uid=" + Binder.getCallingUid()
7825                 + " requires " + permission;
7826         Slog.w(TAG, msg);
7827         throw new SecurityException(msg);
7828     }
7829
7830     /**
7831      * Determine if UID is holding permissions required to access {@link Uri} in
7832      * the given {@link ProviderInfo}. Final permission checking is always done
7833      * in {@link ContentProvider}.
7834      */
7835     private final boolean checkHoldingPermissionsLocked(
7836             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7837         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7838                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7839         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7840             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7841                     != PERMISSION_GRANTED) {
7842                 return false;
7843             }
7844         }
7845         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7846     }
7847
7848     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7849             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7850         if (pi.applicationInfo.uid == uid) {
7851             return true;
7852         } else if (!pi.exported) {
7853             return false;
7854         }
7855
7856         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7857         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7858         try {
7859             // check if target holds top-level <provider> permissions
7860             if (!readMet && pi.readPermission != null && considerUidPermissions
7861                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7862                 readMet = true;
7863             }
7864             if (!writeMet && pi.writePermission != null && considerUidPermissions
7865                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7866                 writeMet = true;
7867             }
7868
7869             // track if unprotected read/write is allowed; any denied
7870             // <path-permission> below removes this ability
7871             boolean allowDefaultRead = pi.readPermission == null;
7872             boolean allowDefaultWrite = pi.writePermission == null;
7873
7874             // check if target holds any <path-permission> that match uri
7875             final PathPermission[] pps = pi.pathPermissions;
7876             if (pps != null) {
7877                 final String path = grantUri.uri.getPath();
7878                 int i = pps.length;
7879                 while (i > 0 && (!readMet || !writeMet)) {
7880                     i--;
7881                     PathPermission pp = pps[i];
7882                     if (pp.match(path)) {
7883                         if (!readMet) {
7884                             final String pprperm = pp.getReadPermission();
7885                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7887                                     + ": match=" + pp.match(path)
7888                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7889                             if (pprperm != null) {
7890                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7891                                         == PERMISSION_GRANTED) {
7892                                     readMet = true;
7893                                 } else {
7894                                     allowDefaultRead = false;
7895                                 }
7896                             }
7897                         }
7898                         if (!writeMet) {
7899                             final String ppwperm = pp.getWritePermission();
7900                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7901                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7902                                     + ": match=" + pp.match(path)
7903                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7904                             if (ppwperm != null) {
7905                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7906                                         == PERMISSION_GRANTED) {
7907                                     writeMet = true;
7908                                 } else {
7909                                     allowDefaultWrite = false;
7910                                 }
7911                             }
7912                         }
7913                     }
7914                 }
7915             }
7916
7917             // grant unprotected <provider> read/write, if not blocked by
7918             // <path-permission> above
7919             if (allowDefaultRead) readMet = true;
7920             if (allowDefaultWrite) writeMet = true;
7921
7922         } catch (RemoteException e) {
7923             return false;
7924         }
7925
7926         return readMet && writeMet;
7927     }
7928
7929     public int getAppStartMode(int uid, String packageName) {
7930         synchronized (this) {
7931             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7932         }
7933     }
7934
7935     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7936             boolean allowWhenForeground) {
7937         UidRecord uidRec = mActiveUids.get(uid);
7938         if (!mLenientBackgroundCheck) {
7939             if (!allowWhenForeground || uidRec == null
7940                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7941                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7942                         packageName) != AppOpsManager.MODE_ALLOWED) {
7943                     return ActivityManager.APP_START_MODE_DELAYED;
7944                 }
7945             }
7946
7947         } else if (uidRec == null || uidRec.idle) {
7948             if (callingPid >= 0) {
7949                 ProcessRecord proc;
7950                 synchronized (mPidsSelfLocked) {
7951                     proc = mPidsSelfLocked.get(callingPid);
7952                 }
7953                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7954                     // Whoever is instigating this is in the foreground, so we will allow it
7955                     // to go through.
7956                     return ActivityManager.APP_START_MODE_NORMAL;
7957                 }
7958             }
7959             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7960                     != AppOpsManager.MODE_ALLOWED) {
7961                 return ActivityManager.APP_START_MODE_DELAYED;
7962             }
7963         }
7964         return ActivityManager.APP_START_MODE_NORMAL;
7965     }
7966
7967     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7968         ProviderInfo pi = null;
7969         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7970         if (cpr != null) {
7971             pi = cpr.info;
7972         } else {
7973             try {
7974                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7975                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7976                         userHandle);
7977             } catch (RemoteException ex) {
7978             }
7979         }
7980         return pi;
7981     }
7982
7983     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7984         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7985         if (targetUris != null) {
7986             return targetUris.get(grantUri);
7987         }
7988         return null;
7989     }
7990
7991     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7992             String targetPkg, int targetUid, GrantUri grantUri) {
7993         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7994         if (targetUris == null) {
7995             targetUris = Maps.newArrayMap();
7996             mGrantedUriPermissions.put(targetUid, targetUris);
7997         }
7998
7999         UriPermission perm = targetUris.get(grantUri);
8000         if (perm == null) {
8001             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8002             targetUris.put(grantUri, perm);
8003         }
8004
8005         return perm;
8006     }
8007
8008     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8009             final int modeFlags) {
8010         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8011         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8012                 : UriPermission.STRENGTH_OWNED;
8013
8014         // Root gets to do everything.
8015         if (uid == 0) {
8016             return true;
8017         }
8018
8019         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8020         if (perms == null) return false;
8021
8022         // First look for exact match
8023         final UriPermission exactPerm = perms.get(grantUri);
8024         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8025             return true;
8026         }
8027
8028         // No exact match, look for prefixes
8029         final int N = perms.size();
8030         for (int i = 0; i < N; i++) {
8031             final UriPermission perm = perms.valueAt(i);
8032             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8033                     && perm.getStrength(modeFlags) >= minStrength) {
8034                 return true;
8035             }
8036         }
8037
8038         return false;
8039     }
8040
8041     /**
8042      * @param uri This uri must NOT contain an embedded userId.
8043      * @param userId The userId in which the uri is to be resolved.
8044      */
8045     @Override
8046     public int checkUriPermission(Uri uri, int pid, int uid,
8047             final int modeFlags, int userId, IBinder callerToken) {
8048         enforceNotIsolatedCaller("checkUriPermission");
8049
8050         // Another redirected-binder-call permissions check as in
8051         // {@link checkPermissionWithToken}.
8052         Identity tlsIdentity = sCallerIdentity.get();
8053         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8054             uid = tlsIdentity.uid;
8055             pid = tlsIdentity.pid;
8056         }
8057
8058         // Our own process gets to do everything.
8059         if (pid == MY_PID) {
8060             return PackageManager.PERMISSION_GRANTED;
8061         }
8062         synchronized (this) {
8063             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8064                     ? PackageManager.PERMISSION_GRANTED
8065                     : PackageManager.PERMISSION_DENIED;
8066         }
8067     }
8068
8069     /**
8070      * Check if the targetPkg can be granted permission to access uri by
8071      * the callingUid using the given modeFlags.  Throws a security exception
8072      * if callingUid is not allowed to do this.  Returns the uid of the target
8073      * if the URI permission grant should be performed; returns -1 if it is not
8074      * needed (for example targetPkg already has permission to access the URI).
8075      * If you already know the uid of the target, you can supply it in
8076      * lastTargetUid else set that to -1.
8077      */
8078     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8079             final int modeFlags, int lastTargetUid) {
8080         if (!Intent.isAccessUriMode(modeFlags)) {
8081             return -1;
8082         }
8083
8084         if (targetPkg != null) {
8085             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8086                     "Checking grant " + targetPkg + " permission to " + grantUri);
8087         }
8088
8089         final IPackageManager pm = AppGlobals.getPackageManager();
8090
8091         // If this is not a content: uri, we can't do anything with it.
8092         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8093             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8094                     "Can't grant URI permission for non-content URI: " + grantUri);
8095             return -1;
8096         }
8097
8098         final String authority = grantUri.uri.getAuthority();
8099         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8100                 MATCH_DEBUG_TRIAGED_MISSING);
8101         if (pi == null) {
8102             Slog.w(TAG, "No content provider found for permission check: " +
8103                     grantUri.uri.toSafeString());
8104             return -1;
8105         }
8106
8107         int targetUid = lastTargetUid;
8108         if (targetUid < 0 && targetPkg != null) {
8109             try {
8110                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8111                         UserHandle.getUserId(callingUid));
8112                 if (targetUid < 0) {
8113                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8114                             "Can't grant URI permission no uid for: " + targetPkg);
8115                     return -1;
8116                 }
8117             } catch (RemoteException ex) {
8118                 return -1;
8119             }
8120         }
8121
8122         if (targetUid >= 0) {
8123             // First...  does the target actually need this permission?
8124             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8125                 // No need to grant the target this permission.
8126                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8127                         "Target " + targetPkg + " already has full permission to " + grantUri);
8128                 return -1;
8129             }
8130         } else {
8131             // First...  there is no target package, so can anyone access it?
8132             boolean allowed = pi.exported;
8133             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8134                 if (pi.readPermission != null) {
8135                     allowed = false;
8136                 }
8137             }
8138             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8139                 if (pi.writePermission != null) {
8140                     allowed = false;
8141                 }
8142             }
8143             if (allowed) {
8144                 return -1;
8145             }
8146         }
8147
8148         /* There is a special cross user grant if:
8149          * - The target is on another user.
8150          * - Apps on the current user can access the uri without any uid permissions.
8151          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8152          * grant uri permissions.
8153          */
8154         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8155                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8156                 modeFlags, false /*without considering the uid permissions*/);
8157
8158         // Second...  is the provider allowing granting of URI permissions?
8159         if (!specialCrossUserGrant) {
8160             if (!pi.grantUriPermissions) {
8161                 throw new SecurityException("Provider " + pi.packageName
8162                         + "/" + pi.name
8163                         + " does not allow granting of Uri permissions (uri "
8164                         + grantUri + ")");
8165             }
8166             if (pi.uriPermissionPatterns != null) {
8167                 final int N = pi.uriPermissionPatterns.length;
8168                 boolean allowed = false;
8169                 for (int i=0; i<N; i++) {
8170                     if (pi.uriPermissionPatterns[i] != null
8171                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8172                         allowed = true;
8173                         break;
8174                     }
8175                 }
8176                 if (!allowed) {
8177                     throw new SecurityException("Provider " + pi.packageName
8178                             + "/" + pi.name
8179                             + " does not allow granting of permission to path of Uri "
8180                             + grantUri);
8181                 }
8182             }
8183         }
8184
8185         // Third...  does the caller itself have permission to access
8186         // this uri?
8187         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8188             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8189                 // Require they hold a strong enough Uri permission
8190                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8191                     throw new SecurityException("Uid " + callingUid
8192                             + " does not have permission to uri " + grantUri);
8193                 }
8194             }
8195         }
8196         return targetUid;
8197     }
8198
8199     /**
8200      * @param uri This uri must NOT contain an embedded userId.
8201      * @param userId The userId in which the uri is to be resolved.
8202      */
8203     @Override
8204     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8205             final int modeFlags, int userId) {
8206         enforceNotIsolatedCaller("checkGrantUriPermission");
8207         synchronized(this) {
8208             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8209                     new GrantUri(userId, uri, false), modeFlags, -1);
8210         }
8211     }
8212
8213     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8214             final int modeFlags, UriPermissionOwner owner) {
8215         if (!Intent.isAccessUriMode(modeFlags)) {
8216             return;
8217         }
8218
8219         // So here we are: the caller has the assumed permission
8220         // to the uri, and the target doesn't.  Let's now give this to
8221         // the target.
8222
8223         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8224                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8225
8226         final String authority = grantUri.uri.getAuthority();
8227         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8228                 MATCH_DEBUG_TRIAGED_MISSING);
8229         if (pi == null) {
8230             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8231             return;
8232         }
8233
8234         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8235             grantUri.prefix = true;
8236         }
8237         final UriPermission perm = findOrCreateUriPermissionLocked(
8238                 pi.packageName, targetPkg, targetUid, grantUri);
8239         perm.grantModes(modeFlags, owner);
8240     }
8241
8242     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8243             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8244         if (targetPkg == null) {
8245             throw new NullPointerException("targetPkg");
8246         }
8247         int targetUid;
8248         final IPackageManager pm = AppGlobals.getPackageManager();
8249         try {
8250             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8251         } catch (RemoteException ex) {
8252             return;
8253         }
8254
8255         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8256                 targetUid);
8257         if (targetUid < 0) {
8258             return;
8259         }
8260
8261         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8262                 owner);
8263     }
8264
8265     static class NeededUriGrants extends ArrayList<GrantUri> {
8266         final String targetPkg;
8267         final int targetUid;
8268         final int flags;
8269
8270         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8271             this.targetPkg = targetPkg;
8272             this.targetUid = targetUid;
8273             this.flags = flags;
8274         }
8275     }
8276
8277     /**
8278      * Like checkGrantUriPermissionLocked, but takes an Intent.
8279      */
8280     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8281             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8282         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8283                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8284                 + " clip=" + (intent != null ? intent.getClipData() : null)
8285                 + " from " + intent + "; flags=0x"
8286                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8287
8288         if (targetPkg == null) {
8289             throw new NullPointerException("targetPkg");
8290         }
8291
8292         if (intent == null) {
8293             return null;
8294         }
8295         Uri data = intent.getData();
8296         ClipData clip = intent.getClipData();
8297         if (data == null && clip == null) {
8298             return null;
8299         }
8300         // Default userId for uris in the intent (if they don't specify it themselves)
8301         int contentUserHint = intent.getContentUserHint();
8302         if (contentUserHint == UserHandle.USER_CURRENT) {
8303             contentUserHint = UserHandle.getUserId(callingUid);
8304         }
8305         final IPackageManager pm = AppGlobals.getPackageManager();
8306         int targetUid;
8307         if (needed != null) {
8308             targetUid = needed.targetUid;
8309         } else {
8310             try {
8311                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8312                         targetUserId);
8313             } catch (RemoteException ex) {
8314                 return null;
8315             }
8316             if (targetUid < 0) {
8317                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8318                         "Can't grant URI permission no uid for: " + targetPkg
8319                         + " on user " + targetUserId);
8320                 return null;
8321             }
8322         }
8323         if (data != null) {
8324             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8325             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8326                     targetUid);
8327             if (targetUid > 0) {
8328                 if (needed == null) {
8329                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8330                 }
8331                 needed.add(grantUri);
8332             }
8333         }
8334         if (clip != null) {
8335             for (int i=0; i<clip.getItemCount(); i++) {
8336                 Uri uri = clip.getItemAt(i).getUri();
8337                 if (uri != null) {
8338                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8339                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8340                             targetUid);
8341                     if (targetUid > 0) {
8342                         if (needed == null) {
8343                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8344                         }
8345                         needed.add(grantUri);
8346                     }
8347                 } else {
8348                     Intent clipIntent = clip.getItemAt(i).getIntent();
8349                     if (clipIntent != null) {
8350                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8351                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8352                         if (newNeeded != null) {
8353                             needed = newNeeded;
8354                         }
8355                     }
8356                 }
8357             }
8358         }
8359
8360         return needed;
8361     }
8362
8363     /**
8364      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8365      */
8366     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8367             UriPermissionOwner owner) {
8368         if (needed != null) {
8369             for (int i=0; i<needed.size(); i++) {
8370                 GrantUri grantUri = needed.get(i);
8371                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8372                         grantUri, needed.flags, owner);
8373             }
8374         }
8375     }
8376
8377     void grantUriPermissionFromIntentLocked(int callingUid,
8378             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8379         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8380                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8381         if (needed == null) {
8382             return;
8383         }
8384
8385         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8386     }
8387
8388     /**
8389      * @param uri This uri must NOT contain an embedded userId.
8390      * @param userId The userId in which the uri is to be resolved.
8391      */
8392     @Override
8393     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8394             final int modeFlags, int userId) {
8395         enforceNotIsolatedCaller("grantUriPermission");
8396         GrantUri grantUri = new GrantUri(userId, uri, false);
8397         synchronized(this) {
8398             final ProcessRecord r = getRecordForAppLocked(caller);
8399             if (r == null) {
8400                 throw new SecurityException("Unable to find app for caller "
8401                         + caller
8402                         + " when granting permission to uri " + grantUri);
8403             }
8404             if (targetPkg == null) {
8405                 throw new IllegalArgumentException("null target");
8406             }
8407             if (grantUri == null) {
8408                 throw new IllegalArgumentException("null uri");
8409             }
8410
8411             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8412                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8413                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8414                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8415
8416             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8417                     UserHandle.getUserId(r.uid));
8418         }
8419     }
8420
8421     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8422         if (perm.modeFlags == 0) {
8423             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8424                     perm.targetUid);
8425             if (perms != null) {
8426                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8427                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8428
8429                 perms.remove(perm.uri);
8430                 if (perms.isEmpty()) {
8431                     mGrantedUriPermissions.remove(perm.targetUid);
8432                 }
8433             }
8434         }
8435     }
8436
8437     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8438         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8439                 "Revoking all granted permissions to " + grantUri);
8440
8441         final IPackageManager pm = AppGlobals.getPackageManager();
8442         final String authority = grantUri.uri.getAuthority();
8443         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8444                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8445         if (pi == null) {
8446             Slog.w(TAG, "No content provider found for permission revoke: "
8447                     + grantUri.toSafeString());
8448             return;
8449         }
8450
8451         // Does the caller have this permission on the URI?
8452         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8453             // If they don't have direct access to the URI, then revoke any
8454             // ownerless URI permissions that have been granted to them.
8455             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8456             if (perms != null) {
8457                 boolean persistChanged = false;
8458                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8459                     final UriPermission perm = it.next();
8460                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8461                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8462                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8463                                 "Revoking non-owned " + perm.targetUid
8464                                 + " permission to " + perm.uri);
8465                         persistChanged |= perm.revokeModes(
8466                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8467                         if (perm.modeFlags == 0) {
8468                             it.remove();
8469                         }
8470                     }
8471                 }
8472                 if (perms.isEmpty()) {
8473                     mGrantedUriPermissions.remove(callingUid);
8474                 }
8475                 if (persistChanged) {
8476                     schedulePersistUriGrants();
8477                 }
8478             }
8479             return;
8480         }
8481
8482         boolean persistChanged = false;
8483
8484         // Go through all of the permissions and remove any that match.
8485         int N = mGrantedUriPermissions.size();
8486         for (int i = 0; i < N; i++) {
8487             final int targetUid = mGrantedUriPermissions.keyAt(i);
8488             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8489
8490             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8491                 final UriPermission perm = it.next();
8492                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8493                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8494                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8495                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8496                     persistChanged |= perm.revokeModes(
8497                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8498                     if (perm.modeFlags == 0) {
8499                         it.remove();
8500                     }
8501                 }
8502             }
8503
8504             if (perms.isEmpty()) {
8505                 mGrantedUriPermissions.remove(targetUid);
8506                 N--;
8507                 i--;
8508             }
8509         }
8510
8511         if (persistChanged) {
8512             schedulePersistUriGrants();
8513         }
8514     }
8515
8516     /**
8517      * @param uri This uri must NOT contain an embedded userId.
8518      * @param userId The userId in which the uri is to be resolved.
8519      */
8520     @Override
8521     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8522             int userId) {
8523         enforceNotIsolatedCaller("revokeUriPermission");
8524         synchronized(this) {
8525             final ProcessRecord r = getRecordForAppLocked(caller);
8526             if (r == null) {
8527                 throw new SecurityException("Unable to find app for caller "
8528                         + caller
8529                         + " when revoking permission to uri " + uri);
8530             }
8531             if (uri == null) {
8532                 Slog.w(TAG, "revokeUriPermission: null uri");
8533                 return;
8534             }
8535
8536             if (!Intent.isAccessUriMode(modeFlags)) {
8537                 return;
8538             }
8539
8540             final String authority = uri.getAuthority();
8541             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8542                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8543             if (pi == null) {
8544                 Slog.w(TAG, "No content provider found for permission revoke: "
8545                         + uri.toSafeString());
8546                 return;
8547             }
8548
8549             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8550         }
8551     }
8552
8553     /**
8554      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8555      * given package.
8556      *
8557      * @param packageName Package name to match, or {@code null} to apply to all
8558      *            packages.
8559      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8560      *            to all users.
8561      * @param persistable If persistable grants should be removed.
8562      */
8563     private void removeUriPermissionsForPackageLocked(
8564             String packageName, int userHandle, boolean persistable) {
8565         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8566             throw new IllegalArgumentException("Must narrow by either package or user");
8567         }
8568
8569         boolean persistChanged = false;
8570
8571         int N = mGrantedUriPermissions.size();
8572         for (int i = 0; i < N; i++) {
8573             final int targetUid = mGrantedUriPermissions.keyAt(i);
8574             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8575
8576             // Only inspect grants matching user
8577             if (userHandle == UserHandle.USER_ALL
8578                     || userHandle == UserHandle.getUserId(targetUid)) {
8579                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8580                     final UriPermission perm = it.next();
8581
8582                     // Only inspect grants matching package
8583                     if (packageName == null || perm.sourcePkg.equals(packageName)
8584                             || perm.targetPkg.equals(packageName)) {
8585                         // Hacky solution as part of fixing a security bug; ignore
8586                         // grants associated with DownloadManager so we don't have
8587                         // to immediately launch it to regrant the permissions
8588                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8589                                 && !persistable) continue;
8590
8591                         persistChanged |= perm.revokeModes(persistable
8592                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8593
8594                         // Only remove when no modes remain; any persisted grants
8595                         // will keep this alive.
8596                         if (perm.modeFlags == 0) {
8597                             it.remove();
8598                         }
8599                     }
8600                 }
8601
8602                 if (perms.isEmpty()) {
8603                     mGrantedUriPermissions.remove(targetUid);
8604                     N--;
8605                     i--;
8606                 }
8607             }
8608         }
8609
8610         if (persistChanged) {
8611             schedulePersistUriGrants();
8612         }
8613     }
8614
8615     @Override
8616     public IBinder newUriPermissionOwner(String name) {
8617         enforceNotIsolatedCaller("newUriPermissionOwner");
8618         synchronized(this) {
8619             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8620             return owner.getExternalTokenLocked();
8621         }
8622     }
8623
8624     @Override
8625     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8626         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8627         synchronized(this) {
8628             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8629             if (r == null) {
8630                 throw new IllegalArgumentException("Activity does not exist; token="
8631                         + activityToken);
8632             }
8633             return r.getUriPermissionsLocked().getExternalTokenLocked();
8634         }
8635     }
8636     /**
8637      * @param uri This uri must NOT contain an embedded userId.
8638      * @param sourceUserId The userId in which the uri is to be resolved.
8639      * @param targetUserId The userId of the app that receives the grant.
8640      */
8641     @Override
8642     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8643             final int modeFlags, int sourceUserId, int targetUserId) {
8644         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8645                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8646                 "grantUriPermissionFromOwner", null);
8647         synchronized(this) {
8648             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8649             if (owner == null) {
8650                 throw new IllegalArgumentException("Unknown owner: " + token);
8651             }
8652             if (fromUid != Binder.getCallingUid()) {
8653                 if (Binder.getCallingUid() != Process.myUid()) {
8654                     // Only system code can grant URI permissions on behalf
8655                     // of other users.
8656                     throw new SecurityException("nice try");
8657                 }
8658             }
8659             if (targetPkg == null) {
8660                 throw new IllegalArgumentException("null target");
8661             }
8662             if (uri == null) {
8663                 throw new IllegalArgumentException("null uri");
8664             }
8665
8666             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8667                     modeFlags, owner, targetUserId);
8668         }
8669     }
8670
8671     /**
8672      * @param uri This uri must NOT contain an embedded userId.
8673      * @param userId The userId in which the uri is to be resolved.
8674      */
8675     @Override
8676     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8677         synchronized(this) {
8678             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8679             if (owner == null) {
8680                 throw new IllegalArgumentException("Unknown owner: " + token);
8681             }
8682
8683             if (uri == null) {
8684                 owner.removeUriPermissionsLocked(mode);
8685             } else {
8686                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8687                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8688             }
8689         }
8690     }
8691
8692     private void schedulePersistUriGrants() {
8693         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8694             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8695                     10 * DateUtils.SECOND_IN_MILLIS);
8696         }
8697     }
8698
8699     private void writeGrantedUriPermissions() {
8700         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8701
8702         // Snapshot permissions so we can persist without lock
8703         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8704         synchronized (this) {
8705             final int size = mGrantedUriPermissions.size();
8706             for (int i = 0; i < size; i++) {
8707                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8708                 for (UriPermission perm : perms.values()) {
8709                     if (perm.persistedModeFlags != 0) {
8710                         persist.add(perm.snapshot());
8711                     }
8712                 }
8713             }
8714         }
8715
8716         FileOutputStream fos = null;
8717         try {
8718             fos = mGrantFile.startWrite();
8719
8720             XmlSerializer out = new FastXmlSerializer();
8721             out.setOutput(fos, StandardCharsets.UTF_8.name());
8722             out.startDocument(null, true);
8723             out.startTag(null, TAG_URI_GRANTS);
8724             for (UriPermission.Snapshot perm : persist) {
8725                 out.startTag(null, TAG_URI_GRANT);
8726                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8727                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8728                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8729                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8730                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8731                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8732                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8733                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8734                 out.endTag(null, TAG_URI_GRANT);
8735             }
8736             out.endTag(null, TAG_URI_GRANTS);
8737             out.endDocument();
8738
8739             mGrantFile.finishWrite(fos);
8740         } catch (IOException e) {
8741             if (fos != null) {
8742                 mGrantFile.failWrite(fos);
8743             }
8744         }
8745     }
8746
8747     private void readGrantedUriPermissionsLocked() {
8748         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8749
8750         final long now = System.currentTimeMillis();
8751
8752         FileInputStream fis = null;
8753         try {
8754             fis = mGrantFile.openRead();
8755             final XmlPullParser in = Xml.newPullParser();
8756             in.setInput(fis, StandardCharsets.UTF_8.name());
8757
8758             int type;
8759             while ((type = in.next()) != END_DOCUMENT) {
8760                 final String tag = in.getName();
8761                 if (type == START_TAG) {
8762                     if (TAG_URI_GRANT.equals(tag)) {
8763                         final int sourceUserId;
8764                         final int targetUserId;
8765                         final int userHandle = readIntAttribute(in,
8766                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8767                         if (userHandle != UserHandle.USER_NULL) {
8768                             // For backwards compatibility.
8769                             sourceUserId = userHandle;
8770                             targetUserId = userHandle;
8771                         } else {
8772                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8773                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8774                         }
8775                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8776                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8777                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8778                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8779                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8780                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8781
8782                         // Sanity check that provider still belongs to source package
8783                         // Both direct boot aware and unaware packages are fine as we
8784                         // will do filtering at query time to avoid multiple parsing.
8785                         final ProviderInfo pi = getProviderInfoLocked(
8786                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8787                                         | MATCH_DIRECT_BOOT_UNAWARE);
8788                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8789                             int targetUid = -1;
8790                             try {
8791                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8792                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8793                             } catch (RemoteException e) {
8794                             }
8795                             if (targetUid != -1) {
8796                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8797                                         sourcePkg, targetPkg, targetUid,
8798                                         new GrantUri(sourceUserId, uri, prefix));
8799                                 perm.initPersistedModes(modeFlags, createdTime);
8800                             }
8801                         } else {
8802                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8803                                     + " but instead found " + pi);
8804                         }
8805                     }
8806                 }
8807             }
8808         } catch (FileNotFoundException e) {
8809             // Missing grants is okay
8810         } catch (IOException e) {
8811             Slog.wtf(TAG, "Failed reading Uri grants", e);
8812         } catch (XmlPullParserException e) {
8813             Slog.wtf(TAG, "Failed reading Uri grants", e);
8814         } finally {
8815             IoUtils.closeQuietly(fis);
8816         }
8817     }
8818
8819     /**
8820      * @param uri This uri must NOT contain an embedded userId.
8821      * @param userId The userId in which the uri is to be resolved.
8822      */
8823     @Override
8824     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8825         enforceNotIsolatedCaller("takePersistableUriPermission");
8826
8827         Preconditions.checkFlagsArgument(modeFlags,
8828                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8829
8830         synchronized (this) {
8831             final int callingUid = Binder.getCallingUid();
8832             boolean persistChanged = false;
8833             GrantUri grantUri = new GrantUri(userId, uri, false);
8834
8835             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8836                     new GrantUri(userId, uri, false));
8837             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8838                     new GrantUri(userId, uri, true));
8839
8840             final boolean exactValid = (exactPerm != null)
8841                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8842             final boolean prefixValid = (prefixPerm != null)
8843                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8844
8845             if (!(exactValid || prefixValid)) {
8846                 throw new SecurityException("No persistable permission grants found for UID "
8847                         + callingUid + " and Uri " + grantUri.toSafeString());
8848             }
8849
8850             if (exactValid) {
8851                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8852             }
8853             if (prefixValid) {
8854                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8855             }
8856
8857             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8858
8859             if (persistChanged) {
8860                 schedulePersistUriGrants();
8861             }
8862         }
8863     }
8864
8865     /**
8866      * @param uri This uri must NOT contain an embedded userId.
8867      * @param userId The userId in which the uri is to be resolved.
8868      */
8869     @Override
8870     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8871         enforceNotIsolatedCaller("releasePersistableUriPermission");
8872
8873         Preconditions.checkFlagsArgument(modeFlags,
8874                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8875
8876         synchronized (this) {
8877             final int callingUid = Binder.getCallingUid();
8878             boolean persistChanged = false;
8879
8880             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8881                     new GrantUri(userId, uri, false));
8882             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8883                     new GrantUri(userId, uri, true));
8884             if (exactPerm == null && prefixPerm == null) {
8885                 throw new SecurityException("No permission grants found for UID " + callingUid
8886                         + " and Uri " + uri.toSafeString());
8887             }
8888
8889             if (exactPerm != null) {
8890                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8891                 removeUriPermissionIfNeededLocked(exactPerm);
8892             }
8893             if (prefixPerm != null) {
8894                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8895                 removeUriPermissionIfNeededLocked(prefixPerm);
8896             }
8897
8898             if (persistChanged) {
8899                 schedulePersistUriGrants();
8900             }
8901         }
8902     }
8903
8904     /**
8905      * Prune any older {@link UriPermission} for the given UID until outstanding
8906      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8907      *
8908      * @return if any mutations occured that require persisting.
8909      */
8910     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8911         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8912         if (perms == null) return false;
8913         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8914
8915         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8916         for (UriPermission perm : perms.values()) {
8917             if (perm.persistedModeFlags != 0) {
8918                 persisted.add(perm);
8919             }
8920         }
8921
8922         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8923         if (trimCount <= 0) return false;
8924
8925         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8926         for (int i = 0; i < trimCount; i++) {
8927             final UriPermission perm = persisted.get(i);
8928
8929             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8930                     "Trimming grant created at " + perm.persistedCreateTime);
8931
8932             perm.releasePersistableModes(~0);
8933             removeUriPermissionIfNeededLocked(perm);
8934         }
8935
8936         return true;
8937     }
8938
8939     @Override
8940     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8941             String packageName, boolean incoming) {
8942         enforceNotIsolatedCaller("getPersistedUriPermissions");
8943         Preconditions.checkNotNull(packageName, "packageName");
8944
8945         final int callingUid = Binder.getCallingUid();
8946         final int callingUserId = UserHandle.getUserId(callingUid);
8947         final IPackageManager pm = AppGlobals.getPackageManager();
8948         try {
8949             final int packageUid = pm.getPackageUid(packageName,
8950                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8951             if (packageUid != callingUid) {
8952                 throw new SecurityException(
8953                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8954             }
8955         } catch (RemoteException e) {
8956             throw new SecurityException("Failed to verify package name ownership");
8957         }
8958
8959         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8960         synchronized (this) {
8961             if (incoming) {
8962                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8963                         callingUid);
8964                 if (perms == null) {
8965                     Slog.w(TAG, "No permission grants found for " + packageName);
8966                 } else {
8967                     for (UriPermission perm : perms.values()) {
8968                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8969                             result.add(perm.buildPersistedPublicApiObject());
8970                         }
8971                     }
8972                 }
8973             } else {
8974                 final int size = mGrantedUriPermissions.size();
8975                 for (int i = 0; i < size; i++) {
8976                     final ArrayMap<GrantUri, UriPermission> perms =
8977                             mGrantedUriPermissions.valueAt(i);
8978                     for (UriPermission perm : perms.values()) {
8979                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8980                             result.add(perm.buildPersistedPublicApiObject());
8981                         }
8982                     }
8983                 }
8984             }
8985         }
8986         return new ParceledListSlice<android.content.UriPermission>(result);
8987     }
8988
8989     @Override
8990     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8991             String packageName, int userId) {
8992         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8993                 "getGrantedUriPermissions");
8994
8995         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8996         synchronized (this) {
8997             final int size = mGrantedUriPermissions.size();
8998             for (int i = 0; i < size; i++) {
8999                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9000                 for (UriPermission perm : perms.values()) {
9001                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9002                             && perm.persistedModeFlags != 0) {
9003                         result.add(perm.buildPersistedPublicApiObject());
9004                     }
9005                 }
9006             }
9007         }
9008         return new ParceledListSlice<android.content.UriPermission>(result);
9009     }
9010
9011     @Override
9012     public void clearGrantedUriPermissions(String packageName, int userId) {
9013         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9014                 "clearGrantedUriPermissions");
9015         removeUriPermissionsForPackageLocked(packageName, userId, true);
9016     }
9017
9018     @Override
9019     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9020         synchronized (this) {
9021             ProcessRecord app =
9022                 who != null ? getRecordForAppLocked(who) : null;
9023             if (app == null) return;
9024
9025             Message msg = Message.obtain();
9026             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9027             msg.obj = app;
9028             msg.arg1 = waiting ? 1 : 0;
9029             mUiHandler.sendMessage(msg);
9030         }
9031     }
9032
9033     @Override
9034     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9035         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9036         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9037         outInfo.availMem = Process.getFreeMemory();
9038         outInfo.totalMem = Process.getTotalMemory();
9039         outInfo.threshold = homeAppMem;
9040         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9041         outInfo.hiddenAppThreshold = cachedAppMem;
9042         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9043                 ProcessList.SERVICE_ADJ);
9044         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9045                 ProcessList.VISIBLE_APP_ADJ);
9046         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9047                 ProcessList.FOREGROUND_APP_ADJ);
9048     }
9049
9050     // =========================================================
9051     // TASK MANAGEMENT
9052     // =========================================================
9053
9054     @Override
9055     public List<IAppTask> getAppTasks(String callingPackage) {
9056         int callingUid = Binder.getCallingUid();
9057         long ident = Binder.clearCallingIdentity();
9058
9059         synchronized(this) {
9060             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9061             try {
9062                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9063
9064                 final int N = mRecentTasks.size();
9065                 for (int i = 0; i < N; i++) {
9066                     TaskRecord tr = mRecentTasks.get(i);
9067                     // Skip tasks that do not match the caller.  We don't need to verify
9068                     // callingPackage, because we are also limiting to callingUid and know
9069                     // that will limit to the correct security sandbox.
9070                     if (tr.effectiveUid != callingUid) {
9071                         continue;
9072                     }
9073                     Intent intent = tr.getBaseIntent();
9074                     if (intent == null ||
9075                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9076                         continue;
9077                     }
9078                     ActivityManager.RecentTaskInfo taskInfo =
9079                             createRecentTaskInfoFromTaskRecord(tr);
9080                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9081                     list.add(taskImpl);
9082                 }
9083             } finally {
9084                 Binder.restoreCallingIdentity(ident);
9085             }
9086             return list;
9087         }
9088     }
9089
9090     @Override
9091     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9092         final int callingUid = Binder.getCallingUid();
9093         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9094
9095         synchronized(this) {
9096             if (DEBUG_ALL) Slog.v(
9097                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9098
9099             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9100                     callingUid);
9101
9102             // TODO: Improve with MRU list from all ActivityStacks.
9103             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9104         }
9105
9106         return list;
9107     }
9108
9109     /**
9110      * Creates a new RecentTaskInfo from a TaskRecord.
9111      */
9112     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9113         // Update the task description to reflect any changes in the task stack
9114         tr.updateTaskDescription();
9115
9116         // Compose the recent task info
9117         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9118         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9119         rti.persistentId = tr.taskId;
9120         rti.baseIntent = new Intent(tr.getBaseIntent());
9121         rti.origActivity = tr.origActivity;
9122         rti.realActivity = tr.realActivity;
9123         rti.description = tr.lastDescription;
9124         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9125         rti.userId = tr.userId;
9126         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9127         rti.firstActiveTime = tr.firstActiveTime;
9128         rti.lastActiveTime = tr.lastActiveTime;
9129         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9130         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9131         rti.numActivities = 0;
9132         if (tr.mBounds != null) {
9133             rti.bounds = new Rect(tr.mBounds);
9134         }
9135         rti.isDockable = tr.canGoInDockedStack();
9136         rti.resizeMode = tr.mResizeMode;
9137
9138         ActivityRecord base = null;
9139         ActivityRecord top = null;
9140         ActivityRecord tmp;
9141
9142         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9143             tmp = tr.mActivities.get(i);
9144             if (tmp.finishing) {
9145                 continue;
9146             }
9147             base = tmp;
9148             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9149                 top = base;
9150             }
9151             rti.numActivities++;
9152         }
9153
9154         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9155         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9156
9157         return rti;
9158     }
9159
9160     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9161         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9162                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9163         if (!allowed) {
9164             if (checkPermission(android.Manifest.permission.GET_TASKS,
9165                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9166                 // Temporary compatibility: some existing apps on the system image may
9167                 // still be requesting the old permission and not switched to the new
9168                 // one; if so, we'll still allow them full access.  This means we need
9169                 // to see if they are holding the old permission and are a system app.
9170                 try {
9171                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9172                         allowed = true;
9173                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9174                                 + " is using old GET_TASKS but privileged; allowing");
9175                     }
9176                 } catch (RemoteException e) {
9177                 }
9178             }
9179         }
9180         if (!allowed) {
9181             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9182                     + " does not hold REAL_GET_TASKS; limiting output");
9183         }
9184         return allowed;
9185     }
9186
9187     @Override
9188     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9189             int userId) {
9190         final int callingUid = Binder.getCallingUid();
9191         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9192                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9193
9194         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9195         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9196         synchronized (this) {
9197             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9198                     callingUid);
9199             final boolean detailed = checkCallingPermission(
9200                     android.Manifest.permission.GET_DETAILED_TASKS)
9201                     == PackageManager.PERMISSION_GRANTED;
9202
9203             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9204                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9205                 return ParceledListSlice.emptyList();
9206             }
9207             mRecentTasks.loadUserRecentsLocked(userId);
9208
9209             final int recentsCount = mRecentTasks.size();
9210             ArrayList<ActivityManager.RecentTaskInfo> res =
9211                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9212
9213             final Set<Integer> includedUsers;
9214             if (includeProfiles) {
9215                 includedUsers = mUserController.getProfileIds(userId);
9216             } else {
9217                 includedUsers = new HashSet<>();
9218             }
9219             includedUsers.add(Integer.valueOf(userId));
9220
9221             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9222                 TaskRecord tr = mRecentTasks.get(i);
9223                 // Only add calling user or related users recent tasks
9224                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9225                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9226                     continue;
9227                 }
9228
9229                 if (tr.realActivitySuspended) {
9230                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9231                     continue;
9232                 }
9233
9234                 // Return the entry if desired by the caller.  We always return
9235                 // the first entry, because callers always expect this to be the
9236                 // foreground app.  We may filter others if the caller has
9237                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9238                 // we should exclude the entry.
9239
9240                 if (i == 0
9241                         || withExcluded
9242                         || (tr.intent == null)
9243                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9244                                 == 0)) {
9245                     if (!allowed) {
9246                         // If the caller doesn't have the GET_TASKS permission, then only
9247                         // allow them to see a small subset of tasks -- their own and home.
9248                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9249                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9250                             continue;
9251                         }
9252                     }
9253                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9254                         if (tr.stack != null && tr.stack.isHomeStack()) {
9255                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9256                                     "Skipping, home stack task: " + tr);
9257                             continue;
9258                         }
9259                     }
9260                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9261                         final ActivityStack stack = tr.stack;
9262                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9263                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9264                                     "Skipping, top task in docked stack: " + tr);
9265                             continue;
9266                         }
9267                     }
9268                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9269                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9270                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9271                                     "Skipping, pinned stack task: " + tr);
9272                             continue;
9273                         }
9274                     }
9275                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9276                         // Don't include auto remove tasks that are finished or finishing.
9277                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9278                                 "Skipping, auto-remove without activity: " + tr);
9279                         continue;
9280                     }
9281                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9282                             && !tr.isAvailable) {
9283                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9284                                 "Skipping, unavail real act: " + tr);
9285                         continue;
9286                     }
9287
9288                     if (!tr.mUserSetupComplete) {
9289                         // Don't include task launched while user is not done setting-up.
9290                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9291                                 "Skipping, user setup not complete: " + tr);
9292                         continue;
9293                     }
9294
9295                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9296                     if (!detailed) {
9297                         rti.baseIntent.replaceExtras((Bundle)null);
9298                     }
9299
9300                     res.add(rti);
9301                     maxNum--;
9302                 }
9303             }
9304             return new ParceledListSlice<>(res);
9305         }
9306     }
9307
9308     @Override
9309     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9310         synchronized (this) {
9311             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9312                     "getTaskThumbnail()");
9313             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9314                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9315             if (tr != null) {
9316                 return tr.getTaskThumbnailLocked();
9317             }
9318         }
9319         return null;
9320     }
9321
9322     @Override
9323     public int addAppTask(IBinder activityToken, Intent intent,
9324             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9325         final int callingUid = Binder.getCallingUid();
9326         final long callingIdent = Binder.clearCallingIdentity();
9327
9328         try {
9329             synchronized (this) {
9330                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9331                 if (r == null) {
9332                     throw new IllegalArgumentException("Activity does not exist; token="
9333                             + activityToken);
9334                 }
9335                 ComponentName comp = intent.getComponent();
9336                 if (comp == null) {
9337                     throw new IllegalArgumentException("Intent " + intent
9338                             + " must specify explicit component");
9339                 }
9340                 if (thumbnail.getWidth() != mThumbnailWidth
9341                         || thumbnail.getHeight() != mThumbnailHeight) {
9342                     throw new IllegalArgumentException("Bad thumbnail size: got "
9343                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9344                             + mThumbnailWidth + "x" + mThumbnailHeight);
9345                 }
9346                 if (intent.getSelector() != null) {
9347                     intent.setSelector(null);
9348                 }
9349                 if (intent.getSourceBounds() != null) {
9350                     intent.setSourceBounds(null);
9351                 }
9352                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9353                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9354                         // The caller has added this as an auto-remove task...  that makes no
9355                         // sense, so turn off auto-remove.
9356                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9357                     }
9358                 }
9359                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9360                     mLastAddedTaskActivity = null;
9361                 }
9362                 ActivityInfo ainfo = mLastAddedTaskActivity;
9363                 if (ainfo == null) {
9364                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9365                             comp, 0, UserHandle.getUserId(callingUid));
9366                     if (ainfo.applicationInfo.uid != callingUid) {
9367                         throw new SecurityException(
9368                                 "Can't add task for another application: target uid="
9369                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9370                     }
9371                 }
9372
9373                 // Use the full screen as the context for the task thumbnail
9374                 final Point displaySize = new Point();
9375                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9376                 r.task.stack.getDisplaySize(displaySize);
9377                 thumbnailInfo.taskWidth = displaySize.x;
9378                 thumbnailInfo.taskHeight = displaySize.y;
9379                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9380
9381                 TaskRecord task = new TaskRecord(this,
9382                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9383                         ainfo, intent, description, thumbnailInfo);
9384
9385                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9386                 if (trimIdx >= 0) {
9387                     // If this would have caused a trim, then we'll abort because that
9388                     // means it would be added at the end of the list but then just removed.
9389                     return INVALID_TASK_ID;
9390                 }
9391
9392                 final int N = mRecentTasks.size();
9393                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9394                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9395                     tr.removedFromRecents();
9396                 }
9397
9398                 task.inRecents = true;
9399                 mRecentTasks.add(task);
9400                 r.task.stack.addTask(task, false, "addAppTask");
9401
9402                 task.setLastThumbnailLocked(thumbnail);
9403                 task.freeLastThumbnail();
9404
9405                 return task.taskId;
9406             }
9407         } finally {
9408             Binder.restoreCallingIdentity(callingIdent);
9409         }
9410     }
9411
9412     @Override
9413     public Point getAppTaskThumbnailSize() {
9414         synchronized (this) {
9415             return new Point(mThumbnailWidth,  mThumbnailHeight);
9416         }
9417     }
9418
9419     @Override
9420     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9421         synchronized (this) {
9422             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9423             if (r != null) {
9424                 r.setTaskDescription(td);
9425                 r.task.updateTaskDescription();
9426             }
9427         }
9428     }
9429
9430     @Override
9431     public void setTaskResizeable(int taskId, int resizeableMode) {
9432         synchronized (this) {
9433             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9434                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9435             if (task == null) {
9436                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9437                 return;
9438             }
9439             if (task.mResizeMode != resizeableMode) {
9440                 task.mResizeMode = resizeableMode;
9441                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9442                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9443                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9444             }
9445         }
9446     }
9447
9448     @Override
9449     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9450         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9451         long ident = Binder.clearCallingIdentity();
9452         try {
9453             synchronized (this) {
9454                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9455                 if (task == null) {
9456                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9457                     return;
9458                 }
9459                 int stackId = task.stack.mStackId;
9460                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9461                 // in crop windows resize mode or if the task size is affected by the docked stack
9462                 // changing size. No need to update configuration.
9463                 if (bounds != null && task.inCropWindowsResizeMode()
9464                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9465                     mWindowManager.scrollTask(task.taskId, bounds);
9466                     return;
9467                 }
9468
9469                 // Place the task in the right stack if it isn't there already based on
9470                 // the requested bounds.
9471                 // The stack transition logic is:
9472                 // - a null bounds on a freeform task moves that task to fullscreen
9473                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9474                 //   that task to freeform
9475                 // - otherwise the task is not moved
9476                 if (!StackId.isTaskResizeAllowed(stackId)) {
9477                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9478                 }
9479                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9480                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9481                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9482                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9483                 }
9484                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9485                 if (stackId != task.stack.mStackId) {
9486                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9487                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9488                     preserveWindow = false;
9489                 }
9490
9491                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9492                         false /* deferResume */);
9493             }
9494         } finally {
9495             Binder.restoreCallingIdentity(ident);
9496         }
9497     }
9498
9499     @Override
9500     public Rect getTaskBounds(int taskId) {
9501         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9502         long ident = Binder.clearCallingIdentity();
9503         Rect rect = new Rect();
9504         try {
9505             synchronized (this) {
9506                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9507                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9508                 if (task == null) {
9509                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9510                     return rect;
9511                 }
9512                 if (task.stack != null) {
9513                     // Return the bounds from window manager since it will be adjusted for various
9514                     // things like the presense of a docked stack for tasks that aren't resizeable.
9515                     mWindowManager.getTaskBounds(task.taskId, rect);
9516                 } else {
9517                     // Task isn't in window manager yet since it isn't associated with a stack.
9518                     // Return the persist value from activity manager
9519                     if (task.mBounds != null) {
9520                         rect.set(task.mBounds);
9521                     } else if (task.mLastNonFullscreenBounds != null) {
9522                         rect.set(task.mLastNonFullscreenBounds);
9523                     }
9524                 }
9525             }
9526         } finally {
9527             Binder.restoreCallingIdentity(ident);
9528         }
9529         return rect;
9530     }
9531
9532     @Override
9533     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9534         if (userId != UserHandle.getCallingUserId()) {
9535             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9536                     "getTaskDescriptionIcon");
9537         }
9538         final File passedIconFile = new File(filePath);
9539         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9540                 passedIconFile.getName());
9541         if (!legitIconFile.getPath().equals(filePath)
9542                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9543             throw new IllegalArgumentException("Bad file path: " + filePath
9544                     + " passed for userId " + userId);
9545         }
9546         return mRecentTasks.getTaskDescriptionIcon(filePath);
9547     }
9548
9549     @Override
9550     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9551             throws RemoteException {
9552         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9553                 opts.getCustomInPlaceResId() == 0) {
9554             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9555                     "with valid animation");
9556         }
9557         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9558         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9559                 opts.getCustomInPlaceResId());
9560         mWindowManager.executeAppTransition();
9561     }
9562
9563     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9564             boolean removeFromRecents) {
9565         if (removeFromRecents) {
9566             mRecentTasks.remove(tr);
9567             tr.removedFromRecents();
9568         }
9569         ComponentName component = tr.getBaseIntent().getComponent();
9570         if (component == null) {
9571             Slog.w(TAG, "No component for base intent of task: " + tr);
9572             return;
9573         }
9574
9575         // Find any running services associated with this app and stop if needed.
9576         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9577
9578         if (!killProcess) {
9579             return;
9580         }
9581
9582         // Determine if the process(es) for this task should be killed.
9583         final String pkg = component.getPackageName();
9584         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9585         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9586         for (int i = 0; i < pmap.size(); i++) {
9587
9588             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9589             for (int j = 0; j < uids.size(); j++) {
9590                 ProcessRecord proc = uids.valueAt(j);
9591                 if (proc.userId != tr.userId) {
9592                     // Don't kill process for a different user.
9593                     continue;
9594                 }
9595                 if (proc == mHomeProcess) {
9596                     // Don't kill the home process along with tasks from the same package.
9597                     continue;
9598                 }
9599                 if (!proc.pkgList.containsKey(pkg)) {
9600                     // Don't kill process that is not associated with this task.
9601                     continue;
9602                 }
9603
9604                 for (int k = 0; k < proc.activities.size(); k++) {
9605                     TaskRecord otherTask = proc.activities.get(k).task;
9606                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9607                         // Don't kill process(es) that has an activity in a different task that is
9608                         // also in recents.
9609                         return;
9610                     }
9611                 }
9612
9613                 if (proc.foregroundServices) {
9614                     // Don't kill process(es) with foreground service.
9615                     return;
9616                 }
9617
9618                 // Add process to kill list.
9619                 procsToKill.add(proc);
9620             }
9621         }
9622
9623         // Kill the running processes.
9624         for (int i = 0; i < procsToKill.size(); i++) {
9625             ProcessRecord pr = procsToKill.get(i);
9626             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9627                     && pr.curReceiver == null) {
9628                 pr.kill("remove task", true);
9629             } else {
9630                 // We delay killing processes that are not in the background or running a receiver.
9631                 pr.waitingToKill = "remove task";
9632             }
9633         }
9634     }
9635
9636     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9637         // Remove all tasks with activities in the specified package from the list of recent tasks
9638         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9639             TaskRecord tr = mRecentTasks.get(i);
9640             if (tr.userId != userId) continue;
9641
9642             ComponentName cn = tr.intent.getComponent();
9643             if (cn != null && cn.getPackageName().equals(packageName)) {
9644                 // If the package name matches, remove the task.
9645                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9646             }
9647         }
9648     }
9649
9650     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9651             int userId) {
9652
9653         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9654             TaskRecord tr = mRecentTasks.get(i);
9655             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9656                 continue;
9657             }
9658
9659             ComponentName cn = tr.intent.getComponent();
9660             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9661                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9662             if (sameComponent) {
9663                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9664             }
9665         }
9666     }
9667
9668     /**
9669      * Removes the task with the specified task id.
9670      *
9671      * @param taskId Identifier of the task to be removed.
9672      * @param killProcess Kill any process associated with the task if possible.
9673      * @param removeFromRecents Whether to also remove the task from recents.
9674      * @return Returns true if the given task was found and removed.
9675      */
9676     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9677             boolean removeFromRecents) {
9678         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9679                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9680         if (tr != null) {
9681             tr.removeTaskActivitiesLocked();
9682             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9683             if (tr.isPersistable) {
9684                 notifyTaskPersisterLocked(null, true);
9685             }
9686             return true;
9687         }
9688         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9689         return false;
9690     }
9691
9692     @Override
9693     public void removeStack(int stackId) {
9694         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9695         if (stackId == HOME_STACK_ID) {
9696             throw new IllegalArgumentException("Removing home stack is not allowed.");
9697         }
9698
9699         synchronized (this) {
9700             final long ident = Binder.clearCallingIdentity();
9701             try {
9702                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9703                 if (stack == null) {
9704                     return;
9705                 }
9706                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9707                 for (int i = tasks.size() - 1; i >= 0; i--) {
9708                     removeTaskByIdLocked(
9709                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9710                 }
9711             } finally {
9712                 Binder.restoreCallingIdentity(ident);
9713             }
9714         }
9715     }
9716
9717     @Override
9718     public boolean removeTask(int taskId) {
9719         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9720         synchronized (this) {
9721             final long ident = Binder.clearCallingIdentity();
9722             try {
9723                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9724             } finally {
9725                 Binder.restoreCallingIdentity(ident);
9726             }
9727         }
9728     }
9729
9730     /**
9731      * TODO: Add mController hook
9732      */
9733     @Override
9734     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9735         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9736
9737         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9738         synchronized(this) {
9739             moveTaskToFrontLocked(taskId, flags, bOptions);
9740         }
9741     }
9742
9743     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9744         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9745
9746         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9747                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9748             ActivityOptions.abort(options);
9749             return;
9750         }
9751         final long origId = Binder.clearCallingIdentity();
9752         try {
9753             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9754             if (task == null) {
9755                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9756                 return;
9757             }
9758             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9759                 mStackSupervisor.showLockTaskToast();
9760                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9761                 return;
9762             }
9763             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9764             if (prev != null && prev.isRecentsActivity()) {
9765                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9766             }
9767             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9768                     false /* forceNonResizable */);
9769         } finally {
9770             Binder.restoreCallingIdentity(origId);
9771         }
9772         ActivityOptions.abort(options);
9773     }
9774
9775     /**
9776      * Moves an activity, and all of the other activities within the same task, to the bottom
9777      * of the history stack.  The activity's order within the task is unchanged.
9778      *
9779      * @param token A reference to the activity we wish to move
9780      * @param nonRoot If false then this only works if the activity is the root
9781      *                of a task; if true it will work for any activity in a task.
9782      * @return Returns true if the move completed, false if not.
9783      */
9784     @Override
9785     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9786         enforceNotIsolatedCaller("moveActivityTaskToBack");
9787         synchronized(this) {
9788             final long origId = Binder.clearCallingIdentity();
9789             try {
9790                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9791                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9792                 if (task != null) {
9793                     if (mStackSupervisor.isLockedTask(task)) {
9794                         mStackSupervisor.showLockTaskToast();
9795                         return false;
9796                     }
9797                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9798                 }
9799             } finally {
9800                 Binder.restoreCallingIdentity(origId);
9801             }
9802         }
9803         return false;
9804     }
9805
9806     @Override
9807     public void moveTaskBackwards(int task) {
9808         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9809                 "moveTaskBackwards()");
9810
9811         synchronized(this) {
9812             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9813                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9814                 return;
9815             }
9816             final long origId = Binder.clearCallingIdentity();
9817             moveTaskBackwardsLocked(task);
9818             Binder.restoreCallingIdentity(origId);
9819         }
9820     }
9821
9822     private final void moveTaskBackwardsLocked(int task) {
9823         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9824     }
9825
9826     @Override
9827     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9828             IActivityContainerCallback callback) throws RemoteException {
9829         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9830         synchronized (this) {
9831             if (parentActivityToken == null) {
9832                 throw new IllegalArgumentException("parent token must not be null");
9833             }
9834             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9835             if (r == null) {
9836                 return null;
9837             }
9838             if (callback == null) {
9839                 throw new IllegalArgumentException("callback must not be null");
9840             }
9841             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9842         }
9843     }
9844
9845     @Override
9846     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9847         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9848         synchronized (this) {
9849             mStackSupervisor.deleteActivityContainer(container);
9850         }
9851     }
9852
9853     @Override
9854     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9855         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9856         synchronized (this) {
9857             final int stackId = mStackSupervisor.getNextStackId();
9858             final ActivityStack stack =
9859                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9860             if (stack == null) {
9861                 return null;
9862             }
9863             return stack.mActivityContainer;
9864         }
9865     }
9866
9867     @Override
9868     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9869         synchronized (this) {
9870             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9871             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9872                 return stack.mActivityContainer.getDisplayId();
9873             }
9874             return Display.DEFAULT_DISPLAY;
9875         }
9876     }
9877
9878     @Override
9879     public int getActivityStackId(IBinder token) throws RemoteException {
9880         synchronized (this) {
9881             ActivityStack stack = ActivityRecord.getStackLocked(token);
9882             if (stack == null) {
9883                 return INVALID_STACK_ID;
9884             }
9885             return stack.mStackId;
9886         }
9887     }
9888
9889     @Override
9890     public void exitFreeformMode(IBinder token) throws RemoteException {
9891         synchronized (this) {
9892             long ident = Binder.clearCallingIdentity();
9893             try {
9894                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9895                 if (r == null) {
9896                     throw new IllegalArgumentException(
9897                             "exitFreeformMode: No activity record matching token=" + token);
9898                 }
9899                 final ActivityStack stack = r.getStackLocked(token);
9900                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9901                     throw new IllegalStateException(
9902                             "exitFreeformMode: You can only go fullscreen from freeform.");
9903                 }
9904                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9905                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9906                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9907             } finally {
9908                 Binder.restoreCallingIdentity(ident);
9909             }
9910         }
9911     }
9912
9913     @Override
9914     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9915         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9916         if (stackId == HOME_STACK_ID) {
9917             throw new IllegalArgumentException(
9918                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9919         }
9920         synchronized (this) {
9921             long ident = Binder.clearCallingIdentity();
9922             try {
9923                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9924                         + " to stackId=" + stackId + " toTop=" + toTop);
9925                 if (stackId == DOCKED_STACK_ID) {
9926                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9927                             null /* initialBounds */);
9928                 }
9929                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9930                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9931                 if (result && stackId == DOCKED_STACK_ID) {
9932                     // If task moved to docked stack - show recents if needed.
9933                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9934                             "moveTaskToDockedStack");
9935                 }
9936             } finally {
9937                 Binder.restoreCallingIdentity(ident);
9938             }
9939         }
9940     }
9941
9942     @Override
9943     public void swapDockedAndFullscreenStack() throws RemoteException {
9944         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9945         synchronized (this) {
9946             long ident = Binder.clearCallingIdentity();
9947             try {
9948                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9949                         FULLSCREEN_WORKSPACE_STACK_ID);
9950                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9951                         : null;
9952                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9953                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9954                         : null;
9955                 if (topTask == null || tasks == null || tasks.size() == 0) {
9956                     Slog.w(TAG,
9957                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9958                     return;
9959                 }
9960
9961                 // TODO: App transition
9962                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9963
9964                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9965                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9966                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9967                         ANIMATE, true /* deferResume */);
9968                 final int size = tasks.size();
9969                 for (int i = 0; i < size; i++) {
9970                     final int id = tasks.get(i).taskId;
9971                     if (id == topTask.taskId) {
9972                         continue;
9973                     }
9974                     mStackSupervisor.moveTaskToStackLocked(id,
9975                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9976                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9977                 }
9978
9979                 // Because we deferred the resume, to avoid conflicts with stack switches while
9980                 // resuming, we need to do it after all the tasks are moved.
9981                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9982                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9983
9984                 mWindowManager.executeAppTransition();
9985             } finally {
9986                 Binder.restoreCallingIdentity(ident);
9987             }
9988         }
9989     }
9990
9991     /**
9992      * Moves the input task to the docked stack.
9993      *
9994      * @param taskId Id of task to move.
9995      * @param createMode The mode the docked stack should be created in if it doesn't exist
9996      *                   already. See
9997      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9998      *                   and
9999      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10000      * @param toTop If the task and stack should be moved to the top.
10001      * @param animate Whether we should play an animation for the moving the task
10002      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10003      *                      docked stack. Pass {@code null} to use default bounds.
10004      */
10005     @Override
10006     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10007             Rect initialBounds, boolean moveHomeStackFront) {
10008         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10009         synchronized (this) {
10010             long ident = Binder.clearCallingIdentity();
10011             try {
10012                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10013                         + " to createMode=" + createMode + " toTop=" + toTop);
10014                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10015                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10016                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10017                         animate, DEFER_RESUME);
10018                 if (moved) {
10019                     if (moveHomeStackFront) {
10020                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10021                     }
10022                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10023                 }
10024                 return moved;
10025             } finally {
10026                 Binder.restoreCallingIdentity(ident);
10027             }
10028         }
10029     }
10030
10031     /**
10032      * Moves the top activity in the input stackId to the pinned stack.
10033      *
10034      * @param stackId Id of stack to move the top activity to pinned stack.
10035      * @param bounds Bounds to use for pinned stack.
10036      *
10037      * @return True if the top activity of the input stack was successfully moved to the pinned
10038      *          stack.
10039      */
10040     @Override
10041     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10042         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10043         synchronized (this) {
10044             if (!mSupportsPictureInPicture) {
10045                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10046                         + "Device doesn't support picture-in-pciture mode");
10047             }
10048
10049             long ident = Binder.clearCallingIdentity();
10050             try {
10051                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10052             } finally {
10053                 Binder.restoreCallingIdentity(ident);
10054             }
10055         }
10056     }
10057
10058     @Override
10059     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10060             boolean preserveWindows, boolean animate, int animationDuration) {
10061         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10062         long ident = Binder.clearCallingIdentity();
10063         try {
10064             synchronized (this) {
10065                 if (animate) {
10066                     if (stackId == PINNED_STACK_ID) {
10067                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10068                     } else {
10069                         throw new IllegalArgumentException("Stack: " + stackId
10070                                 + " doesn't support animated resize.");
10071                     }
10072                 } else {
10073                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10074                             null /* tempTaskInsetBounds */, preserveWindows,
10075                             allowResizeInDockedMode, !DEFER_RESUME);
10076                 }
10077             }
10078         } finally {
10079             Binder.restoreCallingIdentity(ident);
10080         }
10081     }
10082
10083     @Override
10084     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10085             Rect tempDockedTaskInsetBounds,
10086             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10087         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10088                 "resizeDockedStack()");
10089         long ident = Binder.clearCallingIdentity();
10090         try {
10091             synchronized (this) {
10092                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10093                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10094                         PRESERVE_WINDOWS);
10095             }
10096         } finally {
10097             Binder.restoreCallingIdentity(ident);
10098         }
10099     }
10100
10101     @Override
10102     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10103         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10104                 "resizePinnedStack()");
10105         final long ident = Binder.clearCallingIdentity();
10106         try {
10107             synchronized (this) {
10108                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10109             }
10110         } finally {
10111             Binder.restoreCallingIdentity(ident);
10112         }
10113     }
10114
10115     @Override
10116     public void positionTaskInStack(int taskId, int stackId, int position) {
10117         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10118         if (stackId == HOME_STACK_ID) {
10119             throw new IllegalArgumentException(
10120                     "positionTaskInStack: Attempt to change the position of task "
10121                     + taskId + " in/to home stack");
10122         }
10123         synchronized (this) {
10124             long ident = Binder.clearCallingIdentity();
10125             try {
10126                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10127                         "positionTaskInStack: positioning task=" + taskId
10128                         + " in stackId=" + stackId + " at position=" + position);
10129                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10130             } finally {
10131                 Binder.restoreCallingIdentity(ident);
10132             }
10133         }
10134     }
10135
10136     @Override
10137     public List<StackInfo> getAllStackInfos() {
10138         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10139         long ident = Binder.clearCallingIdentity();
10140         try {
10141             synchronized (this) {
10142                 return mStackSupervisor.getAllStackInfosLocked();
10143             }
10144         } finally {
10145             Binder.restoreCallingIdentity(ident);
10146         }
10147     }
10148
10149     @Override
10150     public StackInfo getStackInfo(int stackId) {
10151         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10152         long ident = Binder.clearCallingIdentity();
10153         try {
10154             synchronized (this) {
10155                 return mStackSupervisor.getStackInfoLocked(stackId);
10156             }
10157         } finally {
10158             Binder.restoreCallingIdentity(ident);
10159         }
10160     }
10161
10162     @Override
10163     public boolean isInHomeStack(int taskId) {
10164         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10165         long ident = Binder.clearCallingIdentity();
10166         try {
10167             synchronized (this) {
10168                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10169                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10170                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10171             }
10172         } finally {
10173             Binder.restoreCallingIdentity(ident);
10174         }
10175     }
10176
10177     @Override
10178     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10179         synchronized(this) {
10180             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10181         }
10182     }
10183
10184     @Override
10185     public void updateDeviceOwner(String packageName) {
10186         final int callingUid = Binder.getCallingUid();
10187         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10188             throw new SecurityException("updateDeviceOwner called from non-system process");
10189         }
10190         synchronized (this) {
10191             mDeviceOwnerName = packageName;
10192         }
10193     }
10194
10195     @Override
10196     public void updateLockTaskPackages(int userId, String[] packages) {
10197         final int callingUid = Binder.getCallingUid();
10198         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10199             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10200                     "updateLockTaskPackages()");
10201         }
10202         synchronized (this) {
10203             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10204                     Arrays.toString(packages));
10205             mLockTaskPackages.put(userId, packages);
10206             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10207         }
10208     }
10209
10210
10211     void startLockTaskModeLocked(TaskRecord task) {
10212         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10213         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10214             return;
10215         }
10216
10217         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10218         // is initiated by system after the pinning request was shown and locked mode is initiated
10219         // by an authorized app directly
10220         final int callingUid = Binder.getCallingUid();
10221         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10222         long ident = Binder.clearCallingIdentity();
10223         try {
10224             if (!isSystemInitiated) {
10225                 task.mLockTaskUid = callingUid;
10226                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10227                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10228                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10229                     StatusBarManagerInternal statusBarManager =
10230                             LocalServices.getService(StatusBarManagerInternal.class);
10231                     if (statusBarManager != null) {
10232                         statusBarManager.showScreenPinningRequest(task.taskId);
10233                     }
10234                     return;
10235                 }
10236
10237                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10238                 if (stack == null || task != stack.topTask()) {
10239                     throw new IllegalArgumentException("Invalid task, not in foreground");
10240                 }
10241             }
10242             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10243                     "Locking fully");
10244             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10245                     ActivityManager.LOCK_TASK_MODE_PINNED :
10246                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10247                     "startLockTask", true);
10248         } finally {
10249             Binder.restoreCallingIdentity(ident);
10250         }
10251     }
10252
10253     @Override
10254     public void startLockTaskMode(int taskId) {
10255         synchronized (this) {
10256             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10257             if (task != null) {
10258                 startLockTaskModeLocked(task);
10259             }
10260         }
10261     }
10262
10263     @Override
10264     public void startLockTaskMode(IBinder token) {
10265         synchronized (this) {
10266             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10267             if (r == null) {
10268                 return;
10269             }
10270             final TaskRecord task = r.task;
10271             if (task != null) {
10272                 startLockTaskModeLocked(task);
10273             }
10274         }
10275     }
10276
10277     @Override
10278     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10279         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10280         // This makes inner call to look as if it was initiated by system.
10281         long ident = Binder.clearCallingIdentity();
10282         try {
10283             synchronized (this) {
10284                 startLockTaskMode(taskId);
10285             }
10286         } finally {
10287             Binder.restoreCallingIdentity(ident);
10288         }
10289     }
10290
10291     @Override
10292     public void stopLockTaskMode() {
10293         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10294         if (lockTask == null) {
10295             // Our work here is done.
10296             return;
10297         }
10298
10299         final int callingUid = Binder.getCallingUid();
10300         final int lockTaskUid = lockTask.mLockTaskUid;
10301         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10302         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10303             // Done.
10304             return;
10305         } else {
10306             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10307             // It is possible lockTaskMode was started by the system process because
10308             // android:lockTaskMode is set to a locking value in the application manifest
10309             // instead of the app calling startLockTaskMode. In this case
10310             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10311             // {@link TaskRecord.effectiveUid} instead. Also caller with
10312             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10313             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10314                     && callingUid != lockTaskUid
10315                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10316                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10317                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10318             }
10319         }
10320         long ident = Binder.clearCallingIdentity();
10321         try {
10322             Log.d(TAG, "stopLockTaskMode");
10323             // Stop lock task
10324             synchronized (this) {
10325                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10326                         "stopLockTask", true);
10327             }
10328             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10329             if (tm != null) {
10330                 tm.showInCallScreen(false);
10331             }
10332         } finally {
10333             Binder.restoreCallingIdentity(ident);
10334         }
10335     }
10336
10337     /**
10338      * This API should be called by SystemUI only when user perform certain action to dismiss
10339      * lock task mode. We should only dismiss pinned lock task mode in this case.
10340      */
10341     @Override
10342     public void stopSystemLockTaskMode() throws RemoteException {
10343         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10344             stopLockTaskMode();
10345         } else {
10346             mStackSupervisor.showLockTaskToast();
10347         }
10348     }
10349
10350     @Override
10351     public boolean isInLockTaskMode() {
10352         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10353     }
10354
10355     @Override
10356     public int getLockTaskModeState() {
10357         synchronized (this) {
10358             return mStackSupervisor.getLockTaskModeState();
10359         }
10360     }
10361
10362     @Override
10363     public void showLockTaskEscapeMessage(IBinder token) {
10364         synchronized (this) {
10365             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10366             if (r == null) {
10367                 return;
10368             }
10369             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10370         }
10371     }
10372
10373     // =========================================================
10374     // CONTENT PROVIDERS
10375     // =========================================================
10376
10377     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10378         List<ProviderInfo> providers = null;
10379         try {
10380             providers = AppGlobals.getPackageManager()
10381                     .queryContentProviders(app.processName, app.uid,
10382                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10383                                     | MATCH_DEBUG_TRIAGED_MISSING)
10384                     .getList();
10385         } catch (RemoteException ex) {
10386         }
10387         if (DEBUG_MU) Slog.v(TAG_MU,
10388                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10389         int userId = app.userId;
10390         if (providers != null) {
10391             int N = providers.size();
10392             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10393             for (int i=0; i<N; i++) {
10394                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10395                 ProviderInfo cpi =
10396                     (ProviderInfo)providers.get(i);
10397                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10398                         cpi.name, cpi.flags);
10399                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10400                     // This is a singleton provider, but a user besides the
10401                     // default user is asking to initialize a process it runs
10402                     // in...  well, no, it doesn't actually run in this process,
10403                     // it runs in the process of the default user.  Get rid of it.
10404                     providers.remove(i);
10405                     N--;
10406                     i--;
10407                     continue;
10408                 }
10409
10410                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10411                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10412                 if (cpr == null) {
10413                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10414                     mProviderMap.putProviderByClass(comp, cpr);
10415                 }
10416                 if (DEBUG_MU) Slog.v(TAG_MU,
10417                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10418                 app.pubProviders.put(cpi.name, cpr);
10419                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10420                     // Don't add this if it is a platform component that is marked
10421                     // to run in multiple processes, because this is actually
10422                     // part of the framework so doesn't make sense to track as a
10423                     // separate apk in the process.
10424                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10425                             mProcessStats);
10426                 }
10427                 notifyPackageUse(cpi.applicationInfo.packageName,
10428                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10429             }
10430         }
10431         return providers;
10432     }
10433
10434     /**
10435      * Check if the calling UID has a possible chance at accessing the provider
10436      * at the given authority and user.
10437      */
10438     public String checkContentProviderAccess(String authority, int userId) {
10439         if (userId == UserHandle.USER_ALL) {
10440             mContext.enforceCallingOrSelfPermission(
10441                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10442             userId = UserHandle.getCallingUserId();
10443         }
10444
10445         ProviderInfo cpi = null;
10446         try {
10447             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10448                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10449                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10450                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10451                     userId);
10452         } catch (RemoteException ignored) {
10453         }
10454         if (cpi == null) {
10455             // TODO: make this an outright failure in a future platform release;
10456             // until then anonymous content notifications are unprotected
10457             //return "Failed to find provider " + authority + " for user " + userId;
10458             return null;
10459         }
10460
10461         ProcessRecord r = null;
10462         synchronized (mPidsSelfLocked) {
10463             r = mPidsSelfLocked.get(Binder.getCallingPid());
10464         }
10465         if (r == null) {
10466             return "Failed to find PID " + Binder.getCallingPid();
10467         }
10468
10469         synchronized (this) {
10470             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10471         }
10472     }
10473
10474     /**
10475      * Check if {@link ProcessRecord} has a possible chance at accessing the
10476      * given {@link ProviderInfo}. Final permission checking is always done
10477      * in {@link ContentProvider}.
10478      */
10479     private final String checkContentProviderPermissionLocked(
10480             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10481         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10482         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10483         boolean checkedGrants = false;
10484         if (checkUser) {
10485             // Looking for cross-user grants before enforcing the typical cross-users permissions
10486             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10487             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10488                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10489                     return null;
10490                 }
10491                 checkedGrants = true;
10492             }
10493             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10494                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10495             if (userId != tmpTargetUserId) {
10496                 // When we actually went to determine the final targer user ID, this ended
10497                 // up different than our initial check for the authority.  This is because
10498                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10499                 // SELF.  So we need to re-check the grants again.
10500                 checkedGrants = false;
10501             }
10502         }
10503         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10504                 cpi.applicationInfo.uid, cpi.exported)
10505                 == PackageManager.PERMISSION_GRANTED) {
10506             return null;
10507         }
10508         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10509                 cpi.applicationInfo.uid, cpi.exported)
10510                 == PackageManager.PERMISSION_GRANTED) {
10511             return null;
10512         }
10513
10514         PathPermission[] pps = cpi.pathPermissions;
10515         if (pps != null) {
10516             int i = pps.length;
10517             while (i > 0) {
10518                 i--;
10519                 PathPermission pp = pps[i];
10520                 String pprperm = pp.getReadPermission();
10521                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10522                         cpi.applicationInfo.uid, cpi.exported)
10523                         == PackageManager.PERMISSION_GRANTED) {
10524                     return null;
10525                 }
10526                 String ppwperm = pp.getWritePermission();
10527                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10528                         cpi.applicationInfo.uid, cpi.exported)
10529                         == PackageManager.PERMISSION_GRANTED) {
10530                     return null;
10531                 }
10532             }
10533         }
10534         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10535             return null;
10536         }
10537
10538         String msg;
10539         if (!cpi.exported) {
10540             msg = "Permission Denial: opening provider " + cpi.name
10541                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10542                     + ", uid=" + callingUid + ") that is not exported from uid "
10543                     + cpi.applicationInfo.uid;
10544         } else {
10545             msg = "Permission Denial: opening provider " + cpi.name
10546                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10547                     + ", uid=" + callingUid + ") requires "
10548                     + cpi.readPermission + " or " + cpi.writePermission;
10549         }
10550         Slog.w(TAG, msg);
10551         return msg;
10552     }
10553
10554     /**
10555      * Returns if the ContentProvider has granted a uri to callingUid
10556      */
10557     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10558         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10559         if (perms != null) {
10560             for (int i=perms.size()-1; i>=0; i--) {
10561                 GrantUri grantUri = perms.keyAt(i);
10562                 if (grantUri.sourceUserId == userId || !checkUser) {
10563                     if (matchesProvider(grantUri.uri, cpi)) {
10564                         return true;
10565                     }
10566                 }
10567             }
10568         }
10569         return false;
10570     }
10571
10572     /**
10573      * Returns true if the uri authority is one of the authorities specified in the provider.
10574      */
10575     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10576         String uriAuth = uri.getAuthority();
10577         String cpiAuth = cpi.authority;
10578         if (cpiAuth.indexOf(';') == -1) {
10579             return cpiAuth.equals(uriAuth);
10580         }
10581         String[] cpiAuths = cpiAuth.split(";");
10582         int length = cpiAuths.length;
10583         for (int i = 0; i < length; i++) {
10584             if (cpiAuths[i].equals(uriAuth)) return true;
10585         }
10586         return false;
10587     }
10588
10589     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10590             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10591         if (r != null) {
10592             for (int i=0; i<r.conProviders.size(); i++) {
10593                 ContentProviderConnection conn = r.conProviders.get(i);
10594                 if (conn.provider == cpr) {
10595                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10596                             "Adding provider requested by "
10597                             + r.processName + " from process "
10598                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10599                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10600                     if (stable) {
10601                         conn.stableCount++;
10602                         conn.numStableIncs++;
10603                     } else {
10604                         conn.unstableCount++;
10605                         conn.numUnstableIncs++;
10606                     }
10607                     return conn;
10608                 }
10609             }
10610             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10611             if (stable) {
10612                 conn.stableCount = 1;
10613                 conn.numStableIncs = 1;
10614             } else {
10615                 conn.unstableCount = 1;
10616                 conn.numUnstableIncs = 1;
10617             }
10618             cpr.connections.add(conn);
10619             r.conProviders.add(conn);
10620             startAssociationLocked(r.uid, r.processName, r.curProcState,
10621                     cpr.uid, cpr.name, cpr.info.processName);
10622             return conn;
10623         }
10624         cpr.addExternalProcessHandleLocked(externalProcessToken);
10625         return null;
10626     }
10627
10628     boolean decProviderCountLocked(ContentProviderConnection conn,
10629             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10630         if (conn != null) {
10631             cpr = conn.provider;
10632             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10633                     "Removing provider requested by "
10634                     + conn.client.processName + " from process "
10635                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10636                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10637             if (stable) {
10638                 conn.stableCount--;
10639             } else {
10640                 conn.unstableCount--;
10641             }
10642             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10643                 cpr.connections.remove(conn);
10644                 conn.client.conProviders.remove(conn);
10645                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10646                     // The client is more important than last activity -- note the time this
10647                     // is happening, so we keep the old provider process around a bit as last
10648                     // activity to avoid thrashing it.
10649                     if (cpr.proc != null) {
10650                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10651                     }
10652                 }
10653                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10654                 return true;
10655             }
10656             return false;
10657         }
10658         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10659         return false;
10660     }
10661
10662     private void checkTime(long startTime, String where) {
10663         long now = SystemClock.uptimeMillis();
10664         if ((now-startTime) > 50) {
10665             // If we are taking more than 50ms, log about it.
10666             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10667         }
10668     }
10669
10670     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10671             PROC_SPACE_TERM,
10672             PROC_SPACE_TERM|PROC_PARENS,
10673             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10674     };
10675
10676     private final long[] mProcessStateStatsLongs = new long[1];
10677
10678     boolean isProcessAliveLocked(ProcessRecord proc) {
10679         if (proc.procStatFile == null) {
10680             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10681         }
10682         mProcessStateStatsLongs[0] = 0;
10683         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10684                 mProcessStateStatsLongs, null)) {
10685             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10686             return false;
10687         }
10688         final long state = mProcessStateStatsLongs[0];
10689         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10690                 + (char)state);
10691         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10692     }
10693
10694     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10695             String name, IBinder token, boolean stable, int userId) {
10696         ContentProviderRecord cpr;
10697         ContentProviderConnection conn = null;
10698         ProviderInfo cpi = null;
10699
10700         synchronized(this) {
10701             long startTime = SystemClock.uptimeMillis();
10702
10703             ProcessRecord r = null;
10704             if (caller != null) {
10705                 r = getRecordForAppLocked(caller);
10706                 if (r == null) {
10707                     throw new SecurityException(
10708                             "Unable to find app for caller " + caller
10709                           + " (pid=" + Binder.getCallingPid()
10710                           + ") when getting content provider " + name);
10711                 }
10712             }
10713
10714             boolean checkCrossUser = true;
10715
10716             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10717
10718             // First check if this content provider has been published...
10719             cpr = mProviderMap.getProviderByName(name, userId);
10720             // If that didn't work, check if it exists for user 0 and then
10721             // verify that it's a singleton provider before using it.
10722             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10723                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10724                 if (cpr != null) {
10725                     cpi = cpr.info;
10726                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10727                             cpi.name, cpi.flags)
10728                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10729                         userId = UserHandle.USER_SYSTEM;
10730                         checkCrossUser = false;
10731                     } else {
10732                         cpr = null;
10733                         cpi = null;
10734                     }
10735                 }
10736             }
10737
10738             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10739             if (providerRunning) {
10740                 cpi = cpr.info;
10741                 String msg;
10742                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10743                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10744                         != null) {
10745                     throw new SecurityException(msg);
10746                 }
10747                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10748
10749                 if (r != null && cpr.canRunHere(r)) {
10750                     // This provider has been published or is in the process
10751                     // of being published...  but it is also allowed to run
10752                     // in the caller's process, so don't make a connection
10753                     // and just let the caller instantiate its own instance.
10754                     ContentProviderHolder holder = cpr.newHolder(null);
10755                     // don't give caller the provider object, it needs
10756                     // to make its own.
10757                     holder.provider = null;
10758                     return holder;
10759                 }
10760
10761                 final long origId = Binder.clearCallingIdentity();
10762
10763                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10764
10765                 // In this case the provider instance already exists, so we can
10766                 // return it right away.
10767                 conn = incProviderCountLocked(r, cpr, token, stable);
10768                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10769                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10770                         // If this is a perceptible app accessing the provider,
10771                         // make sure to count it as being accessed and thus
10772                         // back up on the LRU list.  This is good because
10773                         // content providers are often expensive to start.
10774                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10775                         updateLruProcessLocked(cpr.proc, false, null);
10776                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10777                     }
10778                 }
10779
10780                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10781                 final int verifiedAdj = cpr.proc.verifiedAdj;
10782                 boolean success = updateOomAdjLocked(cpr.proc);
10783                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10784                 // if the process has been successfully adjusted.  So to reduce races with
10785                 // it, we will check whether the process still exists.  Note that this doesn't
10786                 // completely get rid of races with LMK killing the process, but should make
10787                 // them much smaller.
10788                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10789                     success = false;
10790                 }
10791                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10792                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10793                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10794                 // NOTE: there is still a race here where a signal could be
10795                 // pending on the process even though we managed to update its
10796                 // adj level.  Not sure what to do about this, but at least
10797                 // the race is now smaller.
10798                 if (!success) {
10799                     // Uh oh...  it looks like the provider's process
10800                     // has been killed on us.  We need to wait for a new
10801                     // process to be started, and make sure its death
10802                     // doesn't kill our process.
10803                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10804                             + " is crashing; detaching " + r);
10805                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10806                     checkTime(startTime, "getContentProviderImpl: before appDied");
10807                     appDiedLocked(cpr.proc);
10808                     checkTime(startTime, "getContentProviderImpl: after appDied");
10809                     if (!lastRef) {
10810                         // This wasn't the last ref our process had on
10811                         // the provider...  we have now been killed, bail.
10812                         return null;
10813                     }
10814                     providerRunning = false;
10815                     conn = null;
10816                 } else {
10817                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10818                 }
10819
10820                 Binder.restoreCallingIdentity(origId);
10821             }
10822
10823             if (!providerRunning) {
10824                 try {
10825                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10826                     cpi = AppGlobals.getPackageManager().
10827                         resolveContentProvider(name,
10828                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10829                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10830                 } catch (RemoteException ex) {
10831                 }
10832                 if (cpi == null) {
10833                     return null;
10834                 }
10835                 // If the provider is a singleton AND
10836                 // (it's a call within the same user || the provider is a
10837                 // privileged app)
10838                 // Then allow connecting to the singleton provider
10839                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10840                         cpi.name, cpi.flags)
10841                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10842                 if (singleton) {
10843                     userId = UserHandle.USER_SYSTEM;
10844                 }
10845                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10846                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10847
10848                 String msg;
10849                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10850                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10851                         != null) {
10852                     throw new SecurityException(msg);
10853                 }
10854                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10855
10856                 if (!mProcessesReady
10857                         && !cpi.processName.equals("system")) {
10858                     // If this content provider does not run in the system
10859                     // process, and the system is not yet ready to run other
10860                     // processes, then fail fast instead of hanging.
10861                     throw new IllegalArgumentException(
10862                             "Attempt to launch content provider before system ready");
10863                 }
10864
10865                 // Make sure that the user who owns this provider is running.  If not,
10866                 // we don't want to allow it to run.
10867                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10868                     Slog.w(TAG, "Unable to launch app "
10869                             + cpi.applicationInfo.packageName + "/"
10870                             + cpi.applicationInfo.uid + " for provider "
10871                             + name + ": user " + userId + " is stopped");
10872                     return null;
10873                 }
10874
10875                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10876                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10877                 cpr = mProviderMap.getProviderByClass(comp, userId);
10878                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10879                 final boolean firstClass = cpr == null;
10880                 if (firstClass) {
10881                     final long ident = Binder.clearCallingIdentity();
10882
10883                     // If permissions need a review before any of the app components can run,
10884                     // we return no provider and launch a review activity if the calling app
10885                     // is in the foreground.
10886                     if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10887                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10888                             return null;
10889                         }
10890                     }
10891
10892                     try {
10893                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10894                         ApplicationInfo ai =
10895                             AppGlobals.getPackageManager().
10896                                 getApplicationInfo(
10897                                         cpi.applicationInfo.packageName,
10898                                         STOCK_PM_FLAGS, userId);
10899                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10900                         if (ai == null) {
10901                             Slog.w(TAG, "No package info for content provider "
10902                                     + cpi.name);
10903                             return null;
10904                         }
10905                         ai = getAppInfoForUser(ai, userId);
10906                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10907                     } catch (RemoteException ex) {
10908                         // pm is in same process, this will never happen.
10909                     } finally {
10910                         Binder.restoreCallingIdentity(ident);
10911                     }
10912                 }
10913
10914                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10915
10916                 if (r != null && cpr.canRunHere(r)) {
10917                     // If this is a multiprocess provider, then just return its
10918                     // info and allow the caller to instantiate it.  Only do
10919                     // this if the provider is the same user as the caller's
10920                     // process, or can run as root (so can be in any process).
10921                     return cpr.newHolder(null);
10922                 }
10923
10924                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10925                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10926                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10927
10928                 // This is single process, and our app is now connecting to it.
10929                 // See if we are already in the process of launching this
10930                 // provider.
10931                 final int N = mLaunchingProviders.size();
10932                 int i;
10933                 for (i = 0; i < N; i++) {
10934                     if (mLaunchingProviders.get(i) == cpr) {
10935                         break;
10936                     }
10937                 }
10938
10939                 // If the provider is not already being launched, then get it
10940                 // started.
10941                 if (i >= N) {
10942                     final long origId = Binder.clearCallingIdentity();
10943
10944                     try {
10945                         // Content provider is now in use, its package can't be stopped.
10946                         try {
10947                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10948                             AppGlobals.getPackageManager().setPackageStoppedState(
10949                                     cpr.appInfo.packageName, false, userId);
10950                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10951                         } catch (RemoteException e) {
10952                         } catch (IllegalArgumentException e) {
10953                             Slog.w(TAG, "Failed trying to unstop package "
10954                                     + cpr.appInfo.packageName + ": " + e);
10955                         }
10956
10957                         // Use existing process if already started
10958                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10959                         ProcessRecord proc = getProcessRecordLocked(
10960                                 cpi.processName, cpr.appInfo.uid, false);
10961                         if (proc != null && proc.thread != null && !proc.killed) {
10962                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10963                                     "Installing in existing process " + proc);
10964                             if (!proc.pubProviders.containsKey(cpi.name)) {
10965                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10966                                 proc.pubProviders.put(cpi.name, cpr);
10967                                 try {
10968                                     proc.thread.scheduleInstallProvider(cpi);
10969                                 } catch (RemoteException e) {
10970                                 }
10971                             }
10972                         } else {
10973                             checkTime(startTime, "getContentProviderImpl: before start process");
10974                             proc = startProcessLocked(cpi.processName,
10975                                     cpr.appInfo, false, 0, "content provider",
10976                                     new ComponentName(cpi.applicationInfo.packageName,
10977                                             cpi.name), false, false, false);
10978                             checkTime(startTime, "getContentProviderImpl: after start process");
10979                             if (proc == null) {
10980                                 Slog.w(TAG, "Unable to launch app "
10981                                         + cpi.applicationInfo.packageName + "/"
10982                                         + cpi.applicationInfo.uid + " for provider "
10983                                         + name + ": process is bad");
10984                                 return null;
10985                             }
10986                         }
10987                         cpr.launchingApp = proc;
10988                         mLaunchingProviders.add(cpr);
10989                     } finally {
10990                         Binder.restoreCallingIdentity(origId);
10991                     }
10992                 }
10993
10994                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10995
10996                 // Make sure the provider is published (the same provider class
10997                 // may be published under multiple names).
10998                 if (firstClass) {
10999                     mProviderMap.putProviderByClass(comp, cpr);
11000                 }
11001
11002                 mProviderMap.putProviderByName(name, cpr);
11003                 conn = incProviderCountLocked(r, cpr, token, stable);
11004                 if (conn != null) {
11005                     conn.waiting = true;
11006                 }
11007             }
11008             checkTime(startTime, "getContentProviderImpl: done!");
11009         }
11010
11011         // Wait for the provider to be published...
11012         synchronized (cpr) {
11013             while (cpr.provider == null) {
11014                 if (cpr.launchingApp == null) {
11015                     Slog.w(TAG, "Unable to launch app "
11016                             + cpi.applicationInfo.packageName + "/"
11017                             + cpi.applicationInfo.uid + " for provider "
11018                             + name + ": launching app became null");
11019                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11020                             UserHandle.getUserId(cpi.applicationInfo.uid),
11021                             cpi.applicationInfo.packageName,
11022                             cpi.applicationInfo.uid, name);
11023                     return null;
11024                 }
11025                 try {
11026                     if (DEBUG_MU) Slog.v(TAG_MU,
11027                             "Waiting to start provider " + cpr
11028                             + " launchingApp=" + cpr.launchingApp);
11029                     if (conn != null) {
11030                         conn.waiting = true;
11031                     }
11032                     cpr.wait();
11033                 } catch (InterruptedException ex) {
11034                 } finally {
11035                     if (conn != null) {
11036                         conn.waiting = false;
11037                     }
11038                 }
11039             }
11040         }
11041         return cpr != null ? cpr.newHolder(conn) : null;
11042     }
11043
11044     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11045             ProcessRecord r, final int userId) {
11046         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11047                 cpi.packageName, userId)) {
11048
11049             final boolean callerForeground = r == null || r.setSchedGroup
11050                     != ProcessList.SCHED_GROUP_BACKGROUND;
11051
11052             // Show a permission review UI only for starting from a foreground app
11053             if (!callerForeground) {
11054                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11055                         + cpi.packageName + " requires a permissions review");
11056                 return false;
11057             }
11058
11059             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11060             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11061                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11062             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11063
11064             if (DEBUG_PERMISSIONS_REVIEW) {
11065                 Slog.i(TAG, "u" + userId + " Launching permission review "
11066                         + "for package " + cpi.packageName);
11067             }
11068
11069             final UserHandle userHandle = new UserHandle(userId);
11070             mHandler.post(new Runnable() {
11071                 @Override
11072                 public void run() {
11073                     mContext.startActivityAsUser(intent, userHandle);
11074                 }
11075             });
11076
11077             return false;
11078         }
11079
11080         return true;
11081     }
11082
11083     PackageManagerInternal getPackageManagerInternalLocked() {
11084         if (mPackageManagerInt == null) {
11085             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11086         }
11087         return mPackageManagerInt;
11088     }
11089
11090     @Override
11091     public final ContentProviderHolder getContentProvider(
11092             IApplicationThread caller, String name, int userId, boolean stable) {
11093         enforceNotIsolatedCaller("getContentProvider");
11094         if (caller == null) {
11095             String msg = "null IApplicationThread when getting content provider "
11096                     + name;
11097             Slog.w(TAG, msg);
11098             throw new SecurityException(msg);
11099         }
11100         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11101         // with cross-user grant.
11102         return getContentProviderImpl(caller, name, null, stable, userId);
11103     }
11104
11105     public ContentProviderHolder getContentProviderExternal(
11106             String name, int userId, IBinder token) {
11107         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11108             "Do not have permission in call getContentProviderExternal()");
11109         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11110                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11111         return getContentProviderExternalUnchecked(name, token, userId);
11112     }
11113
11114     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11115             IBinder token, int userId) {
11116         return getContentProviderImpl(null, name, token, true, userId);
11117     }
11118
11119     /**
11120      * Drop a content provider from a ProcessRecord's bookkeeping
11121      */
11122     public void removeContentProvider(IBinder connection, boolean stable) {
11123         enforceNotIsolatedCaller("removeContentProvider");
11124         long ident = Binder.clearCallingIdentity();
11125         try {
11126             synchronized (this) {
11127                 ContentProviderConnection conn;
11128                 try {
11129                     conn = (ContentProviderConnection)connection;
11130                 } catch (ClassCastException e) {
11131                     String msg ="removeContentProvider: " + connection
11132                             + " not a ContentProviderConnection";
11133                     Slog.w(TAG, msg);
11134                     throw new IllegalArgumentException(msg);
11135                 }
11136                 if (conn == null) {
11137                     throw new NullPointerException("connection is null");
11138                 }
11139                 if (decProviderCountLocked(conn, null, null, stable)) {
11140                     updateOomAdjLocked();
11141                 }
11142             }
11143         } finally {
11144             Binder.restoreCallingIdentity(ident);
11145         }
11146     }
11147
11148     public void removeContentProviderExternal(String name, IBinder token) {
11149         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11150             "Do not have permission in call removeContentProviderExternal()");
11151         int userId = UserHandle.getCallingUserId();
11152         long ident = Binder.clearCallingIdentity();
11153         try {
11154             removeContentProviderExternalUnchecked(name, token, userId);
11155         } finally {
11156             Binder.restoreCallingIdentity(ident);
11157         }
11158     }
11159
11160     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11161         synchronized (this) {
11162             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11163             if(cpr == null) {
11164                 //remove from mProvidersByClass
11165                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11166                 return;
11167             }
11168
11169             //update content provider record entry info
11170             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11171             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11172             if (localCpr.hasExternalProcessHandles()) {
11173                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11174                     updateOomAdjLocked();
11175                 } else {
11176                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11177                             + " with no external reference for token: "
11178                             + token + ".");
11179                 }
11180             } else {
11181                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11182                         + " with no external references.");
11183             }
11184         }
11185     }
11186
11187     public final void publishContentProviders(IApplicationThread caller,
11188             List<ContentProviderHolder> providers) {
11189         if (providers == null) {
11190             return;
11191         }
11192
11193         enforceNotIsolatedCaller("publishContentProviders");
11194         synchronized (this) {
11195             final ProcessRecord r = getRecordForAppLocked(caller);
11196             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11197             if (r == null) {
11198                 throw new SecurityException(
11199                         "Unable to find app for caller " + caller
11200                       + " (pid=" + Binder.getCallingPid()
11201                       + ") when publishing content providers");
11202             }
11203
11204             final long origId = Binder.clearCallingIdentity();
11205
11206             final int N = providers.size();
11207             for (int i = 0; i < N; i++) {
11208                 ContentProviderHolder src = providers.get(i);
11209                 if (src == null || src.info == null || src.provider == null) {
11210                     continue;
11211                 }
11212                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11213                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11214                 if (dst != null) {
11215                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11216                     mProviderMap.putProviderByClass(comp, dst);
11217                     String names[] = dst.info.authority.split(";");
11218                     for (int j = 0; j < names.length; j++) {
11219                         mProviderMap.putProviderByName(names[j], dst);
11220                     }
11221
11222                     int launchingCount = mLaunchingProviders.size();
11223                     int j;
11224                     boolean wasInLaunchingProviders = false;
11225                     for (j = 0; j < launchingCount; j++) {
11226                         if (mLaunchingProviders.get(j) == dst) {
11227                             mLaunchingProviders.remove(j);
11228                             wasInLaunchingProviders = true;
11229                             j--;
11230                             launchingCount--;
11231                         }
11232                     }
11233                     if (wasInLaunchingProviders) {
11234                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11235                     }
11236                     synchronized (dst) {
11237                         dst.provider = src.provider;
11238                         dst.proc = r;
11239                         dst.notifyAll();
11240                     }
11241                     updateOomAdjLocked(r);
11242                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11243                             src.info.authority);
11244                 }
11245             }
11246
11247             Binder.restoreCallingIdentity(origId);
11248         }
11249     }
11250
11251     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11252         ContentProviderConnection conn;
11253         try {
11254             conn = (ContentProviderConnection)connection;
11255         } catch (ClassCastException e) {
11256             String msg ="refContentProvider: " + connection
11257                     + " not a ContentProviderConnection";
11258             Slog.w(TAG, msg);
11259             throw new IllegalArgumentException(msg);
11260         }
11261         if (conn == null) {
11262             throw new NullPointerException("connection is null");
11263         }
11264
11265         synchronized (this) {
11266             if (stable > 0) {
11267                 conn.numStableIncs += stable;
11268             }
11269             stable = conn.stableCount + stable;
11270             if (stable < 0) {
11271                 throw new IllegalStateException("stableCount < 0: " + stable);
11272             }
11273
11274             if (unstable > 0) {
11275                 conn.numUnstableIncs += unstable;
11276             }
11277             unstable = conn.unstableCount + unstable;
11278             if (unstable < 0) {
11279                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11280             }
11281
11282             if ((stable+unstable) <= 0) {
11283                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11284                         + stable + " unstable=" + unstable);
11285             }
11286             conn.stableCount = stable;
11287             conn.unstableCount = unstable;
11288             return !conn.dead;
11289         }
11290     }
11291
11292     public void unstableProviderDied(IBinder connection) {
11293         ContentProviderConnection conn;
11294         try {
11295             conn = (ContentProviderConnection)connection;
11296         } catch (ClassCastException e) {
11297             String msg ="refContentProvider: " + connection
11298                     + " not a ContentProviderConnection";
11299             Slog.w(TAG, msg);
11300             throw new IllegalArgumentException(msg);
11301         }
11302         if (conn == null) {
11303             throw new NullPointerException("connection is null");
11304         }
11305
11306         // Safely retrieve the content provider associated with the connection.
11307         IContentProvider provider;
11308         synchronized (this) {
11309             provider = conn.provider.provider;
11310         }
11311
11312         if (provider == null) {
11313             // Um, yeah, we're way ahead of you.
11314             return;
11315         }
11316
11317         // Make sure the caller is being honest with us.
11318         if (provider.asBinder().pingBinder()) {
11319             // Er, no, still looks good to us.
11320             synchronized (this) {
11321                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11322                         + " says " + conn + " died, but we don't agree");
11323                 return;
11324             }
11325         }
11326
11327         // Well look at that!  It's dead!
11328         synchronized (this) {
11329             if (conn.provider.provider != provider) {
11330                 // But something changed...  good enough.
11331                 return;
11332             }
11333
11334             ProcessRecord proc = conn.provider.proc;
11335             if (proc == null || proc.thread == null) {
11336                 // Seems like the process is already cleaned up.
11337                 return;
11338             }
11339
11340             // As far as we're concerned, this is just like receiving a
11341             // death notification...  just a bit prematurely.
11342             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11343                     + ") early provider death");
11344             final long ident = Binder.clearCallingIdentity();
11345             try {
11346                 appDiedLocked(proc);
11347             } finally {
11348                 Binder.restoreCallingIdentity(ident);
11349             }
11350         }
11351     }
11352
11353     @Override
11354     public void appNotRespondingViaProvider(IBinder connection) {
11355         enforceCallingPermission(
11356                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11357
11358         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11359         if (conn == null) {
11360             Slog.w(TAG, "ContentProviderConnection is null");
11361             return;
11362         }
11363
11364         final ProcessRecord host = conn.provider.proc;
11365         if (host == null) {
11366             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11367             return;
11368         }
11369
11370         mHandler.post(new Runnable() {
11371             @Override
11372             public void run() {
11373                 mAppErrors.appNotResponding(host, null, null, false,
11374                         "ContentProvider not responding");
11375             }
11376         });
11377     }
11378
11379     public final void installSystemProviders() {
11380         List<ProviderInfo> providers;
11381         synchronized (this) {
11382             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11383             providers = generateApplicationProvidersLocked(app);
11384             if (providers != null) {
11385                 for (int i=providers.size()-1; i>=0; i--) {
11386                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11387                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11388                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11389                                 + ": not system .apk");
11390                         providers.remove(i);
11391                     }
11392                 }
11393             }
11394         }
11395         if (providers != null) {
11396             mSystemThread.installSystemProviders(providers);
11397         }
11398
11399         mCoreSettingsObserver = new CoreSettingsObserver(this);
11400         mFontScaleSettingObserver = new FontScaleSettingObserver();
11401
11402         //mUsageStatsService.monitorPackages();
11403     }
11404
11405     private void startPersistentApps(int matchFlags) {
11406         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11407
11408         synchronized (this) {
11409             try {
11410                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11411                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11412                 for (ApplicationInfo app : apps) {
11413                     if (!"android".equals(app.packageName)) {
11414                         addAppLocked(app, false, null /* ABI override */);
11415                     }
11416                 }
11417             } catch (RemoteException ex) {
11418             }
11419         }
11420     }
11421
11422     /**
11423      * When a user is unlocked, we need to install encryption-unaware providers
11424      * belonging to any running apps.
11425      */
11426     private void installEncryptionUnawareProviders(int userId) {
11427         // We're only interested in providers that are encryption unaware, and
11428         // we don't care about uninstalled apps, since there's no way they're
11429         // running at this point.
11430         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11431
11432         synchronized (this) {
11433             final int NP = mProcessNames.getMap().size();
11434             for (int ip = 0; ip < NP; ip++) {
11435                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11436                 final int NA = apps.size();
11437                 for (int ia = 0; ia < NA; ia++) {
11438                     final ProcessRecord app = apps.valueAt(ia);
11439                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11440
11441                     final int NG = app.pkgList.size();
11442                     for (int ig = 0; ig < NG; ig++) {
11443                         try {
11444                             final String pkgName = app.pkgList.keyAt(ig);
11445                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11446                                     .getPackageInfo(pkgName, matchFlags, userId);
11447                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11448                                 for (ProviderInfo pi : pkgInfo.providers) {
11449                                     // TODO: keep in sync with generateApplicationProvidersLocked
11450                                     final boolean processMatch = Objects.equals(pi.processName,
11451                                             app.processName) || pi.multiprocess;
11452                                     final boolean userMatch = isSingleton(pi.processName,
11453                                             pi.applicationInfo, pi.name, pi.flags)
11454                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11455                                     if (processMatch && userMatch) {
11456                                         Log.v(TAG, "Installing " + pi);
11457                                         app.thread.scheduleInstallProvider(pi);
11458                                     } else {
11459                                         Log.v(TAG, "Skipping " + pi);
11460                                     }
11461                                 }
11462                             }
11463                         } catch (RemoteException ignored) {
11464                         }
11465                     }
11466                 }
11467             }
11468         }
11469     }
11470
11471     /**
11472      * Allows apps to retrieve the MIME type of a URI.
11473      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11474      * users, then it does not need permission to access the ContentProvider.
11475      * Either, it needs cross-user uri grants.
11476      *
11477      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11478      *
11479      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11480      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11481      */
11482     public String getProviderMimeType(Uri uri, int userId) {
11483         enforceNotIsolatedCaller("getProviderMimeType");
11484         final String name = uri.getAuthority();
11485         int callingUid = Binder.getCallingUid();
11486         int callingPid = Binder.getCallingPid();
11487         long ident = 0;
11488         boolean clearedIdentity = false;
11489         synchronized (this) {
11490             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11491         }
11492         if (canClearIdentity(callingPid, callingUid, userId)) {
11493             clearedIdentity = true;
11494             ident = Binder.clearCallingIdentity();
11495         }
11496         ContentProviderHolder holder = null;
11497         try {
11498             holder = getContentProviderExternalUnchecked(name, null, userId);
11499             if (holder != null) {
11500                 return holder.provider.getType(uri);
11501             }
11502         } catch (RemoteException e) {
11503             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11504             return null;
11505         } catch (Exception e) {
11506             Log.w(TAG, "Exception while determining type of " + uri, e);
11507             return null;
11508         } finally {
11509             // We need to clear the identity to call removeContentProviderExternalUnchecked
11510             if (!clearedIdentity) {
11511                 ident = Binder.clearCallingIdentity();
11512             }
11513             try {
11514                 if (holder != null) {
11515                     removeContentProviderExternalUnchecked(name, null, userId);
11516                 }
11517             } finally {
11518                 Binder.restoreCallingIdentity(ident);
11519             }
11520         }
11521
11522         return null;
11523     }
11524
11525     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11526         if (UserHandle.getUserId(callingUid) == userId) {
11527             return true;
11528         }
11529         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11530                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11531                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11532                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11533                 return true;
11534         }
11535         return false;
11536     }
11537
11538     // =========================================================
11539     // GLOBAL MANAGEMENT
11540     // =========================================================
11541
11542     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11543             boolean isolated, int isolatedUid) {
11544         String proc = customProcess != null ? customProcess : info.processName;
11545         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11546         final int userId = UserHandle.getUserId(info.uid);
11547         int uid = info.uid;
11548         if (isolated) {
11549             if (isolatedUid == 0) {
11550                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11551                 while (true) {
11552                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11553                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11554                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11555                     }
11556                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11557                     mNextIsolatedProcessUid++;
11558                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11559                         // No process for this uid, use it.
11560                         break;
11561                     }
11562                     stepsLeft--;
11563                     if (stepsLeft <= 0) {
11564                         return null;
11565                     }
11566                 }
11567             } else {
11568                 // Special case for startIsolatedProcess (internal only), where
11569                 // the uid of the isolated process is specified by the caller.
11570                 uid = isolatedUid;
11571             }
11572
11573             // Register the isolated UID with this application so BatteryStats knows to
11574             // attribute resource usage to the application.
11575             //
11576             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11577             // about the process state of the isolated UID *before* it is registered with the
11578             // owning application.
11579             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11580         }
11581         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11582         if (!mBooted && !mBooting
11583                 && userId == UserHandle.USER_SYSTEM
11584                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11585             r.persistent = true;
11586         }
11587         addProcessNameLocked(r);
11588         return r;
11589     }
11590
11591     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11592             String abiOverride) {
11593         ProcessRecord app;
11594         if (!isolated) {
11595             app = getProcessRecordLocked(info.processName, info.uid, true);
11596         } else {
11597             app = null;
11598         }
11599
11600         if (app == null) {
11601             app = newProcessRecordLocked(info, null, isolated, 0);
11602             updateLruProcessLocked(app, false, null);
11603             updateOomAdjLocked();
11604         }
11605
11606         // This package really, really can not be stopped.
11607         try {
11608             AppGlobals.getPackageManager().setPackageStoppedState(
11609                     info.packageName, false, UserHandle.getUserId(app.uid));
11610         } catch (RemoteException e) {
11611         } catch (IllegalArgumentException e) {
11612             Slog.w(TAG, "Failed trying to unstop package "
11613                     + info.packageName + ": " + e);
11614         }
11615
11616         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11617             app.persistent = true;
11618             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11619         }
11620         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11621             mPersistentStartingProcesses.add(app);
11622             startProcessLocked(app, "added application", app.processName, abiOverride,
11623                     null /* entryPoint */, null /* entryPointArgs */);
11624         }
11625
11626         return app;
11627     }
11628
11629     public void unhandledBack() {
11630         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11631                 "unhandledBack()");
11632
11633         synchronized(this) {
11634             final long origId = Binder.clearCallingIdentity();
11635             try {
11636                 getFocusedStack().unhandledBackLocked();
11637             } finally {
11638                 Binder.restoreCallingIdentity(origId);
11639             }
11640         }
11641     }
11642
11643     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11644         enforceNotIsolatedCaller("openContentUri");
11645         final int userId = UserHandle.getCallingUserId();
11646         String name = uri.getAuthority();
11647         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11648         ParcelFileDescriptor pfd = null;
11649         if (cph != null) {
11650             // We record the binder invoker's uid in thread-local storage before
11651             // going to the content provider to open the file.  Later, in the code
11652             // that handles all permissions checks, we look for this uid and use
11653             // that rather than the Activity Manager's own uid.  The effect is that
11654             // we do the check against the caller's permissions even though it looks
11655             // to the content provider like the Activity Manager itself is making
11656             // the request.
11657             Binder token = new Binder();
11658             sCallerIdentity.set(new Identity(
11659                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11660             try {
11661                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11662             } catch (FileNotFoundException e) {
11663                 // do nothing; pfd will be returned null
11664             } finally {
11665                 // Ensure that whatever happens, we clean up the identity state
11666                 sCallerIdentity.remove();
11667                 // Ensure we're done with the provider.
11668                 removeContentProviderExternalUnchecked(name, null, userId);
11669             }
11670         } else {
11671             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11672         }
11673         return pfd;
11674     }
11675
11676     // Actually is sleeping or shutting down or whatever else in the future
11677     // is an inactive state.
11678     boolean isSleepingOrShuttingDownLocked() {
11679         return isSleepingLocked() || mShuttingDown;
11680     }
11681
11682     boolean isShuttingDownLocked() {
11683         return mShuttingDown;
11684     }
11685
11686     boolean isSleepingLocked() {
11687         return mSleeping;
11688     }
11689
11690     void onWakefulnessChanged(int wakefulness) {
11691         synchronized(this) {
11692             mWakefulness = wakefulness;
11693             updateSleepIfNeededLocked();
11694         }
11695     }
11696
11697     void finishRunningVoiceLocked() {
11698         if (mRunningVoice != null) {
11699             mRunningVoice = null;
11700             mVoiceWakeLock.release();
11701             updateSleepIfNeededLocked();
11702         }
11703     }
11704
11705     void startTimeTrackingFocusedActivityLocked() {
11706         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11707             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11708         }
11709     }
11710
11711     void updateSleepIfNeededLocked() {
11712         if (mSleeping && !shouldSleepLocked()) {
11713             mSleeping = false;
11714             startTimeTrackingFocusedActivityLocked();
11715             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11716             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11717             sendNotifyVrManagerOfSleepState(false);
11718             updateOomAdjLocked();
11719         } else if (!mSleeping && shouldSleepLocked()) {
11720             mSleeping = true;
11721             if (mCurAppTimeTracker != null) {
11722                 mCurAppTimeTracker.stop();
11723             }
11724             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11725             mStackSupervisor.goingToSleepLocked();
11726             sendNotifyVrManagerOfSleepState(true);
11727             updateOomAdjLocked();
11728
11729             // Initialize the wake times of all processes.
11730             checkExcessivePowerUsageLocked(false);
11731             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11732             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11733             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11734         }
11735     }
11736
11737     private boolean shouldSleepLocked() {
11738         // Resume applications while running a voice interactor.
11739         if (mRunningVoice != null) {
11740             return false;
11741         }
11742
11743         // TODO: Transform the lock screen state into a sleep token instead.
11744         switch (mWakefulness) {
11745             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11746             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11747             case PowerManagerInternal.WAKEFULNESS_DOZING:
11748                 // Pause applications whenever the lock screen is shown or any sleep
11749                 // tokens have been acquired.
11750                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11751             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11752             default:
11753                 // If we're asleep then pause applications unconditionally.
11754                 return true;
11755         }
11756     }
11757
11758     /** Pokes the task persister. */
11759     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11760         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11761     }
11762
11763     /** Notifies all listeners when the task stack has changed. */
11764     void notifyTaskStackChangedLocked() {
11765         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11766         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11767         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11768         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11769     }
11770
11771     /** Notifies all listeners when an Activity is pinned. */
11772     void notifyActivityPinnedLocked() {
11773         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11774         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11775     }
11776
11777     /**
11778      * Notifies all listeners when an attempt was made to start an an activity that is already
11779      * running in the pinned stack and the activity was not actually started, but the task is
11780      * either brought to the front or a new Intent is delivered to it.
11781      */
11782     void notifyPinnedActivityRestartAttemptLocked() {
11783         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11784         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11785     }
11786
11787     /** Notifies all listeners when the pinned stack animation ends. */
11788     @Override
11789     public void notifyPinnedStackAnimationEnded() {
11790         synchronized (this) {
11791             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11792             mHandler.obtainMessage(
11793                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11794         }
11795     }
11796
11797     @Override
11798     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11799         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11800     }
11801
11802     @Override
11803     public boolean shutdown(int timeout) {
11804         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11805                 != PackageManager.PERMISSION_GRANTED) {
11806             throw new SecurityException("Requires permission "
11807                     + android.Manifest.permission.SHUTDOWN);
11808         }
11809
11810         boolean timedout = false;
11811
11812         synchronized(this) {
11813             mShuttingDown = true;
11814             updateEventDispatchingLocked();
11815             timedout = mStackSupervisor.shutdownLocked(timeout);
11816         }
11817
11818         mAppOpsService.shutdown();
11819         if (mUsageStatsService != null) {
11820             mUsageStatsService.prepareShutdown();
11821         }
11822         mBatteryStatsService.shutdown();
11823         synchronized (this) {
11824             mProcessStats.shutdownLocked();
11825             notifyTaskPersisterLocked(null, true);
11826         }
11827
11828         return timedout;
11829     }
11830
11831     public final void activitySlept(IBinder token) {
11832         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11833
11834         final long origId = Binder.clearCallingIdentity();
11835
11836         synchronized (this) {
11837             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11838             if (r != null) {
11839                 mStackSupervisor.activitySleptLocked(r);
11840             }
11841         }
11842
11843         Binder.restoreCallingIdentity(origId);
11844     }
11845
11846     private String lockScreenShownToString() {
11847         switch (mLockScreenShown) {
11848             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11849             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11850             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11851             default: return "Unknown=" + mLockScreenShown;
11852         }
11853     }
11854
11855     void logLockScreen(String msg) {
11856         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11857                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11858                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11859                 + " mSleeping=" + mSleeping);
11860     }
11861
11862     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11863         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11864         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11865         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11866             boolean wasRunningVoice = mRunningVoice != null;
11867             mRunningVoice = session;
11868             if (!wasRunningVoice) {
11869                 mVoiceWakeLock.acquire();
11870                 updateSleepIfNeededLocked();
11871             }
11872         }
11873     }
11874
11875     private void updateEventDispatchingLocked() {
11876         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11877     }
11878
11879     public void setLockScreenShown(boolean showing, boolean occluded) {
11880         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11881                 != PackageManager.PERMISSION_GRANTED) {
11882             throw new SecurityException("Requires permission "
11883                     + android.Manifest.permission.DEVICE_POWER);
11884         }
11885
11886         synchronized(this) {
11887             long ident = Binder.clearCallingIdentity();
11888             try {
11889                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11890                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11891                 if (showing && occluded) {
11892                     // The lock screen is currently showing, but is occluded by a window that can
11893                     // show on top of the lock screen. In this can we want to dismiss the docked
11894                     // stack since it will be complicated/risky to try to put the activity on top
11895                     // of the lock screen in the right fullscreen configuration.
11896                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11897                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11898                 }
11899
11900                 updateSleepIfNeededLocked();
11901             } finally {
11902                 Binder.restoreCallingIdentity(ident);
11903             }
11904         }
11905     }
11906
11907     @Override
11908     public void notifyLockedProfile(@UserIdInt int userId) {
11909         try {
11910             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11911                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11912             }
11913         } catch (RemoteException ex) {
11914             throw new SecurityException("Fail to check is caller a privileged app", ex);
11915         }
11916
11917         synchronized (this) {
11918             if (mStackSupervisor.isUserLockedProfile(userId)) {
11919                 final long ident = Binder.clearCallingIdentity();
11920                 try {
11921                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11922
11923                     // Drop locked freeform tasks out into the fullscreen stack.
11924                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11925                     //       where they were before, but in an obscured state.
11926                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11927
11928                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11929                         // If there is no device lock, we will show the profile's credential page.
11930                         mActivityStarter.showConfirmDeviceCredential(userId);
11931                     } else {
11932                         // Showing launcher to avoid user entering credential twice.
11933                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11934                     }
11935                 } finally {
11936                     Binder.restoreCallingIdentity(ident);
11937                 }
11938             }
11939         }
11940     }
11941
11942     @Override
11943     public void startConfirmDeviceCredentialIntent(Intent intent) {
11944         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11945         synchronized (this) {
11946             final long ident = Binder.clearCallingIdentity();
11947             try {
11948                 mActivityStarter.startConfirmCredentialIntent(intent);
11949             } finally {
11950                 Binder.restoreCallingIdentity(ident);
11951             }
11952         }
11953     }
11954
11955     @Override
11956     public void stopAppSwitches() {
11957         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11958                 != PackageManager.PERMISSION_GRANTED) {
11959             throw new SecurityException("viewquires permission "
11960                     + android.Manifest.permission.STOP_APP_SWITCHES);
11961         }
11962
11963         synchronized(this) {
11964             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11965                     + APP_SWITCH_DELAY_TIME;
11966             mDidAppSwitch = false;
11967             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11968             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11969             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11970         }
11971     }
11972
11973     public void resumeAppSwitches() {
11974         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11975                 != PackageManager.PERMISSION_GRANTED) {
11976             throw new SecurityException("Requires permission "
11977                     + android.Manifest.permission.STOP_APP_SWITCHES);
11978         }
11979
11980         synchronized(this) {
11981             // Note that we don't execute any pending app switches... we will
11982             // let those wait until either the timeout, or the next start
11983             // activity request.
11984             mAppSwitchesAllowedTime = 0;
11985         }
11986     }
11987
11988     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11989             int callingPid, int callingUid, String name) {
11990         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11991             return true;
11992         }
11993
11994         int perm = checkComponentPermission(
11995                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11996                 sourceUid, -1, true);
11997         if (perm == PackageManager.PERMISSION_GRANTED) {
11998             return true;
11999         }
12000
12001         // If the actual IPC caller is different from the logical source, then
12002         // also see if they are allowed to control app switches.
12003         if (callingUid != -1 && callingUid != sourceUid) {
12004             perm = checkComponentPermission(
12005                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12006                     callingUid, -1, true);
12007             if (perm == PackageManager.PERMISSION_GRANTED) {
12008                 return true;
12009             }
12010         }
12011
12012         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12013         return false;
12014     }
12015
12016     public void setDebugApp(String packageName, boolean waitForDebugger,
12017             boolean persistent) {
12018         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12019                 "setDebugApp()");
12020
12021         long ident = Binder.clearCallingIdentity();
12022         try {
12023             // Note that this is not really thread safe if there are multiple
12024             // callers into it at the same time, but that's not a situation we
12025             // care about.
12026             if (persistent) {
12027                 final ContentResolver resolver = mContext.getContentResolver();
12028                 Settings.Global.putString(
12029                     resolver, Settings.Global.DEBUG_APP,
12030                     packageName);
12031                 Settings.Global.putInt(
12032                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12033                     waitForDebugger ? 1 : 0);
12034             }
12035
12036             synchronized (this) {
12037                 if (!persistent) {
12038                     mOrigDebugApp = mDebugApp;
12039                     mOrigWaitForDebugger = mWaitForDebugger;
12040                 }
12041                 mDebugApp = packageName;
12042                 mWaitForDebugger = waitForDebugger;
12043                 mDebugTransient = !persistent;
12044                 if (packageName != null) {
12045                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12046                             false, UserHandle.USER_ALL, "set debug app");
12047                 }
12048             }
12049         } finally {
12050             Binder.restoreCallingIdentity(ident);
12051         }
12052     }
12053
12054     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12055         synchronized (this) {
12056             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12057             if (!isDebuggable) {
12058                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12059                     throw new SecurityException("Process not debuggable: " + app.packageName);
12060                 }
12061             }
12062
12063             mTrackAllocationApp = processName;
12064         }
12065     }
12066
12067     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12068         synchronized (this) {
12069             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12070             if (!isDebuggable) {
12071                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12072                     throw new SecurityException("Process not debuggable: " + app.packageName);
12073                 }
12074             }
12075             mProfileApp = processName;
12076             mProfileFile = profilerInfo.profileFile;
12077             if (mProfileFd != null) {
12078                 try {
12079                     mProfileFd.close();
12080                 } catch (IOException e) {
12081                 }
12082                 mProfileFd = null;
12083             }
12084             mProfileFd = profilerInfo.profileFd;
12085             mSamplingInterval = profilerInfo.samplingInterval;
12086             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12087             mProfileType = 0;
12088         }
12089     }
12090
12091     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12092         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12093         if (!isDebuggable) {
12094             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12095                 throw new SecurityException("Process not debuggable: " + app.packageName);
12096             }
12097         }
12098         mNativeDebuggingApp = processName;
12099     }
12100
12101     @Override
12102     public void setAlwaysFinish(boolean enabled) {
12103         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12104                 "setAlwaysFinish()");
12105
12106         long ident = Binder.clearCallingIdentity();
12107         try {
12108             Settings.Global.putInt(
12109                     mContext.getContentResolver(),
12110                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12111
12112             synchronized (this) {
12113                 mAlwaysFinishActivities = enabled;
12114             }
12115         } finally {
12116             Binder.restoreCallingIdentity(ident);
12117         }
12118     }
12119
12120     @Override
12121     public void setLenientBackgroundCheck(boolean enabled) {
12122         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12123                 "setLenientBackgroundCheck()");
12124
12125         long ident = Binder.clearCallingIdentity();
12126         try {
12127             Settings.Global.putInt(
12128                     mContext.getContentResolver(),
12129                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12130
12131             synchronized (this) {
12132                 mLenientBackgroundCheck = enabled;
12133             }
12134         } finally {
12135             Binder.restoreCallingIdentity(ident);
12136         }
12137     }
12138
12139     @Override
12140     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12141         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12142                 "setActivityController()");
12143         synchronized (this) {
12144             mController = controller;
12145             mControllerIsAMonkey = imAMonkey;
12146             Watchdog.getInstance().setActivityController(controller);
12147         }
12148     }
12149
12150     @Override
12151     public void setUserIsMonkey(boolean userIsMonkey) {
12152         synchronized (this) {
12153             synchronized (mPidsSelfLocked) {
12154                 final int callingPid = Binder.getCallingPid();
12155                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12156                 if (precessRecord == null) {
12157                     throw new SecurityException("Unknown process: " + callingPid);
12158                 }
12159                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12160                     throw new SecurityException("Only an instrumentation process "
12161                             + "with a UiAutomation can call setUserIsMonkey");
12162                 }
12163             }
12164             mUserIsMonkey = userIsMonkey;
12165         }
12166     }
12167
12168     @Override
12169     public boolean isUserAMonkey() {
12170         synchronized (this) {
12171             // If there is a controller also implies the user is a monkey.
12172             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12173         }
12174     }
12175
12176     public void requestBugReport(int bugreportType) {
12177         String service = null;
12178         switch (bugreportType) {
12179             case ActivityManager.BUGREPORT_OPTION_FULL:
12180                 service = "bugreport";
12181                 break;
12182             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12183                 service = "bugreportplus";
12184                 break;
12185             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12186                 service = "bugreportremote";
12187                 break;
12188             case ActivityManager.BUGREPORT_OPTION_WEAR:
12189                 service = "bugreportwear";
12190                 break;
12191             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12192                 service = "bugreportelefony";
12193                 break;
12194         }
12195         if (service == null) {
12196             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12197                     + bugreportType);
12198         }
12199         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12200         SystemProperties.set("ctl.start", service);
12201     }
12202
12203     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12204         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12205     }
12206
12207     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12208         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12209             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12210         }
12211         return KEY_DISPATCHING_TIMEOUT;
12212     }
12213
12214     @Override
12215     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12216         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12217                 != PackageManager.PERMISSION_GRANTED) {
12218             throw new SecurityException("Requires permission "
12219                     + android.Manifest.permission.FILTER_EVENTS);
12220         }
12221         ProcessRecord proc;
12222         long timeout;
12223         synchronized (this) {
12224             synchronized (mPidsSelfLocked) {
12225                 proc = mPidsSelfLocked.get(pid);
12226             }
12227             timeout = getInputDispatchingTimeoutLocked(proc);
12228         }
12229
12230         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12231             return -1;
12232         }
12233
12234         return timeout;
12235     }
12236
12237     /**
12238      * Handle input dispatching timeouts.
12239      * Returns whether input dispatching should be aborted or not.
12240      */
12241     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12242             final ActivityRecord activity, final ActivityRecord parent,
12243             final boolean aboveSystem, String reason) {
12244         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12245                 != PackageManager.PERMISSION_GRANTED) {
12246             throw new SecurityException("Requires permission "
12247                     + android.Manifest.permission.FILTER_EVENTS);
12248         }
12249
12250         final String annotation;
12251         if (reason == null) {
12252             annotation = "Input dispatching timed out";
12253         } else {
12254             annotation = "Input dispatching timed out (" + reason + ")";
12255         }
12256
12257         if (proc != null) {
12258             synchronized (this) {
12259                 if (proc.debugging) {
12260                     return false;
12261                 }
12262
12263                 if (mDidDexOpt) {
12264                     // Give more time since we were dexopting.
12265                     mDidDexOpt = false;
12266                     return false;
12267                 }
12268
12269                 if (proc.instrumentationClass != null) {
12270                     Bundle info = new Bundle();
12271                     info.putString("shortMsg", "keyDispatchingTimedOut");
12272                     info.putString("longMsg", annotation);
12273                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12274                     return true;
12275                 }
12276             }
12277             mHandler.post(new Runnable() {
12278                 @Override
12279                 public void run() {
12280                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12281                 }
12282             });
12283         }
12284
12285         return true;
12286     }
12287
12288     @Override
12289     public Bundle getAssistContextExtras(int requestType) {
12290         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12291                 null, null, true /* focused */, true /* newSessionId */,
12292                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12293         if (pae == null) {
12294             return null;
12295         }
12296         synchronized (pae) {
12297             while (!pae.haveResult) {
12298                 try {
12299                     pae.wait();
12300                 } catch (InterruptedException e) {
12301                 }
12302             }
12303         }
12304         synchronized (this) {
12305             buildAssistBundleLocked(pae, pae.result);
12306             mPendingAssistExtras.remove(pae);
12307             mUiHandler.removeCallbacks(pae);
12308         }
12309         return pae.extras;
12310     }
12311
12312     @Override
12313     public boolean isAssistDataAllowedOnCurrentActivity() {
12314         int userId;
12315         synchronized (this) {
12316             userId = mUserController.getCurrentUserIdLocked();
12317             ActivityRecord activity = getFocusedStack().topActivity();
12318             if (activity == null) {
12319                 return false;
12320             }
12321             userId = activity.userId;
12322         }
12323         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12324                 Context.DEVICE_POLICY_SERVICE);
12325         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12326     }
12327
12328     @Override
12329     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12330         long ident = Binder.clearCallingIdentity();
12331         try {
12332             synchronized (this) {
12333                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12334                 ActivityRecord top = getFocusedStack().topActivity();
12335                 if (top != caller) {
12336                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12337                             + " is not current top " + top);
12338                     return false;
12339                 }
12340                 if (!top.nowVisible) {
12341                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12342                             + " is not visible");
12343                     return false;
12344                 }
12345             }
12346             AssistUtils utils = new AssistUtils(mContext);
12347             return utils.showSessionForActiveService(args,
12348                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12349         } finally {
12350             Binder.restoreCallingIdentity(ident);
12351         }
12352     }
12353
12354     @Override
12355     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12356             Bundle receiverExtras,
12357             IBinder activityToken, boolean focused, boolean newSessionId) {
12358         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12359                 activityToken, focused, newSessionId,
12360                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12361                 != null;
12362     }
12363
12364     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12365             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12366             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12367         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12368                 "enqueueAssistContext()");
12369         synchronized (this) {
12370             ActivityRecord activity = getFocusedStack().topActivity();
12371             if (activity == null) {
12372                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12373                 return null;
12374             }
12375             if (activity.app == null || activity.app.thread == null) {
12376                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12377                 return null;
12378             }
12379             if (focused) {
12380                 if (activityToken != null) {
12381                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12382                     if (activity != caller) {
12383                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12384                                 + " is not current top " + activity);
12385                         return null;
12386                     }
12387                 }
12388             } else {
12389                 activity = ActivityRecord.forTokenLocked(activityToken);
12390                 if (activity == null) {
12391                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12392                             + " couldn't be found");
12393                     return null;
12394                 }
12395             }
12396
12397             PendingAssistExtras pae;
12398             Bundle extras = new Bundle();
12399             if (args != null) {
12400                 extras.putAll(args);
12401             }
12402             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12403             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12404             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12405                     userHandle);
12406             // Increment the sessionId if necessary
12407             if (newSessionId) {
12408                 mViSessionId++;
12409             }
12410             try {
12411                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12412                         requestType, mViSessionId);
12413                 mPendingAssistExtras.add(pae);
12414                 mUiHandler.postDelayed(pae, timeout);
12415             } catch (RemoteException e) {
12416                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12417                 return null;
12418             }
12419             return pae;
12420         }
12421     }
12422
12423     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12424         IResultReceiver receiver;
12425         synchronized (this) {
12426             mPendingAssistExtras.remove(pae);
12427             receiver = pae.receiver;
12428         }
12429         if (receiver != null) {
12430             // Caller wants result sent back to them.
12431             Bundle sendBundle = new Bundle();
12432             // At least return the receiver extras
12433             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12434                     pae.receiverExtras);
12435             try {
12436                 pae.receiver.send(0, sendBundle);
12437             } catch (RemoteException e) {
12438             }
12439         }
12440     }
12441
12442     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12443         if (result != null) {
12444             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12445         }
12446         if (pae.hint != null) {
12447             pae.extras.putBoolean(pae.hint, true);
12448         }
12449     }
12450
12451     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12452             AssistContent content, Uri referrer) {
12453         PendingAssistExtras pae = (PendingAssistExtras)token;
12454         synchronized (pae) {
12455             pae.result = extras;
12456             pae.structure = structure;
12457             pae.content = content;
12458             if (referrer != null) {
12459                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12460             }
12461             pae.haveResult = true;
12462             pae.notifyAll();
12463             if (pae.intent == null && pae.receiver == null) {
12464                 // Caller is just waiting for the result.
12465                 return;
12466             }
12467         }
12468
12469         // We are now ready to launch the assist activity.
12470         IResultReceiver sendReceiver = null;
12471         Bundle sendBundle = null;
12472         synchronized (this) {
12473             buildAssistBundleLocked(pae, extras);
12474             boolean exists = mPendingAssistExtras.remove(pae);
12475             mUiHandler.removeCallbacks(pae);
12476             if (!exists) {
12477                 // Timed out.
12478                 return;
12479             }
12480             if ((sendReceiver=pae.receiver) != null) {
12481                 // Caller wants result sent back to them.
12482                 sendBundle = new Bundle();
12483                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12484                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12485                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12486                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12487                         pae.receiverExtras);
12488             }
12489         }
12490         if (sendReceiver != null) {
12491             try {
12492                 sendReceiver.send(0, sendBundle);
12493             } catch (RemoteException e) {
12494             }
12495             return;
12496         }
12497
12498         long ident = Binder.clearCallingIdentity();
12499         try {
12500             pae.intent.replaceExtras(pae.extras);
12501             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12502                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12503                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12504             closeSystemDialogs("assist");
12505             try {
12506                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12507             } catch (ActivityNotFoundException e) {
12508                 Slog.w(TAG, "No activity to handle assist action.", e);
12509             }
12510         } finally {
12511             Binder.restoreCallingIdentity(ident);
12512         }
12513     }
12514
12515     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12516             Bundle args) {
12517         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12518                 true /* focused */, true /* newSessionId */,
12519                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12520     }
12521
12522     public void registerProcessObserver(IProcessObserver observer) {
12523         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12524                 "registerProcessObserver()");
12525         synchronized (this) {
12526             mProcessObservers.register(observer);
12527         }
12528     }
12529
12530     @Override
12531     public void unregisterProcessObserver(IProcessObserver observer) {
12532         synchronized (this) {
12533             mProcessObservers.unregister(observer);
12534         }
12535     }
12536
12537     @Override
12538     public void registerUidObserver(IUidObserver observer, int which) {
12539         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12540                 "registerUidObserver()");
12541         synchronized (this) {
12542             mUidObservers.register(observer, which);
12543         }
12544     }
12545
12546     @Override
12547     public void unregisterUidObserver(IUidObserver observer) {
12548         synchronized (this) {
12549             mUidObservers.unregister(observer);
12550         }
12551     }
12552
12553     @Override
12554     public boolean convertFromTranslucent(IBinder token) {
12555         final long origId = Binder.clearCallingIdentity();
12556         try {
12557             synchronized (this) {
12558                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12559                 if (r == null) {
12560                     return false;
12561                 }
12562                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12563                 if (translucentChanged) {
12564                     r.task.stack.releaseBackgroundResources(r);
12565                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12566                 }
12567                 mWindowManager.setAppFullscreen(token, true);
12568                 return translucentChanged;
12569             }
12570         } finally {
12571             Binder.restoreCallingIdentity(origId);
12572         }
12573     }
12574
12575     @Override
12576     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12577         final long origId = Binder.clearCallingIdentity();
12578         try {
12579             synchronized (this) {
12580                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12581                 if (r == null) {
12582                     return false;
12583                 }
12584                 int index = r.task.mActivities.lastIndexOf(r);
12585                 if (index > 0) {
12586                     ActivityRecord under = r.task.mActivities.get(index - 1);
12587                     under.returningOptions = options;
12588                 }
12589                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12590                 if (translucentChanged) {
12591                     r.task.stack.convertActivityToTranslucent(r);
12592                 }
12593                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12594                 mWindowManager.setAppFullscreen(token, false);
12595                 return translucentChanged;
12596             }
12597         } finally {
12598             Binder.restoreCallingIdentity(origId);
12599         }
12600     }
12601
12602     @Override
12603     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12604         final long origId = Binder.clearCallingIdentity();
12605         try {
12606             synchronized (this) {
12607                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12608                 if (r != null) {
12609                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12610                 }
12611             }
12612             return false;
12613         } finally {
12614             Binder.restoreCallingIdentity(origId);
12615         }
12616     }
12617
12618     @Override
12619     public boolean isBackgroundVisibleBehind(IBinder token) {
12620         final long origId = Binder.clearCallingIdentity();
12621         try {
12622             synchronized (this) {
12623                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12624                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12625                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12626                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12627                 return visible;
12628             }
12629         } finally {
12630             Binder.restoreCallingIdentity(origId);
12631         }
12632     }
12633
12634     @Override
12635     public ActivityOptions getActivityOptions(IBinder token) {
12636         final long origId = Binder.clearCallingIdentity();
12637         try {
12638             synchronized (this) {
12639                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12640                 if (r != null) {
12641                     final ActivityOptions activityOptions = r.pendingOptions;
12642                     r.pendingOptions = null;
12643                     return activityOptions;
12644                 }
12645                 return null;
12646             }
12647         } finally {
12648             Binder.restoreCallingIdentity(origId);
12649         }
12650     }
12651
12652     @Override
12653     public void setImmersive(IBinder token, boolean immersive) {
12654         synchronized(this) {
12655             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12656             if (r == null) {
12657                 throw new IllegalArgumentException();
12658             }
12659             r.immersive = immersive;
12660
12661             // update associated state if we're frontmost
12662             if (r == mFocusedActivity) {
12663                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12664                 applyUpdateLockStateLocked(r);
12665             }
12666         }
12667     }
12668
12669     @Override
12670     public boolean isImmersive(IBinder token) {
12671         synchronized (this) {
12672             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12673             if (r == null) {
12674                 throw new IllegalArgumentException();
12675             }
12676             return r.immersive;
12677         }
12678     }
12679
12680     public void setVrThread(int tid) {
12681         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12682             throw new UnsupportedOperationException("VR mode not supported on this device!");
12683         }
12684
12685         synchronized (this) {
12686             ProcessRecord proc;
12687             synchronized (mPidsSelfLocked) {
12688                 final int pid = Binder.getCallingPid();
12689                 proc = mPidsSelfLocked.get(pid);
12690
12691                 if (proc != null && mInVrMode && tid >= 0) {
12692                     // ensure the tid belongs to the process
12693                     if (!Process.isThreadInProcess(pid, tid)) {
12694                         throw new IllegalArgumentException("VR thread does not belong to process");
12695                     }
12696
12697                     // reset existing VR thread to CFS if this thread still exists and belongs to
12698                     // the calling process
12699                     if (proc.vrThreadTid != 0
12700                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12701                         try {
12702                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12703                         } catch (IllegalArgumentException e) {
12704                             // Ignore this.  Only occurs in race condition where previous VR thread
12705                             // was destroyed during this method call.
12706                         }
12707                     }
12708
12709                     proc.vrThreadTid = tid;
12710
12711                     // promote to FIFO now if the tid is non-zero
12712                     try {
12713                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12714                             proc.vrThreadTid > 0) {
12715                             Process.setThreadScheduler(proc.vrThreadTid,
12716                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12717                         }
12718                     } catch (IllegalArgumentException e) {
12719                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12720                                + " not exist:\n" + e);
12721                     }
12722                 }
12723             }
12724         }
12725     }
12726
12727     @Override
12728     public void setRenderThread(int tid) {
12729         synchronized (this) {
12730             ProcessRecord proc;
12731             synchronized (mPidsSelfLocked) {
12732                 int pid = Binder.getCallingPid();
12733                 proc = mPidsSelfLocked.get(pid);
12734                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12735                     // ensure the tid belongs to the process
12736                     if (!Process.isThreadInProcess(pid, tid)) {
12737                         throw new IllegalArgumentException(
12738                             "Render thread does not belong to process");
12739                     }
12740                     proc.renderThreadTid = tid;
12741                     if (DEBUG_OOM_ADJ) {
12742                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12743                     }
12744                     // promote to FIFO now
12745                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12746                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12747                         if (mUseFifoUiScheduling) {
12748                             Process.setThreadScheduler(proc.renderThreadTid,
12749                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12750                         } else {
12751                             Process.setThreadPriority(proc.renderThreadTid, -10);
12752                         }
12753                     }
12754                 } else {
12755                     if (DEBUG_OOM_ADJ) {
12756                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12757                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12758                                mUseFifoUiScheduling);
12759                     }
12760                 }
12761             }
12762         }
12763     }
12764
12765     @Override
12766     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12767         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12768             throw new UnsupportedOperationException("VR mode not supported on this device!");
12769         }
12770
12771         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12772
12773         ActivityRecord r;
12774         synchronized (this) {
12775             r = ActivityRecord.isInStackLocked(token);
12776         }
12777
12778         if (r == null) {
12779             throw new IllegalArgumentException();
12780         }
12781
12782         int err;
12783         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12784                 VrManagerInternal.NO_ERROR) {
12785             return err;
12786         }
12787
12788         synchronized(this) {
12789             r.requestedVrComponent = (enabled) ? packageName : null;
12790
12791             // Update associated state if this activity is currently focused
12792             if (r == mFocusedActivity) {
12793                 applyUpdateVrModeLocked(r);
12794             }
12795             return 0;
12796         }
12797     }
12798
12799     @Override
12800     public boolean isVrModePackageEnabled(ComponentName packageName) {
12801         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12802             throw new UnsupportedOperationException("VR mode not supported on this device!");
12803         }
12804
12805         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12806
12807         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12808                 VrManagerInternal.NO_ERROR;
12809     }
12810
12811     public boolean isTopActivityImmersive() {
12812         enforceNotIsolatedCaller("startActivity");
12813         synchronized (this) {
12814             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12815             return (r != null) ? r.immersive : false;
12816         }
12817     }
12818
12819     @Override
12820     public boolean isTopOfTask(IBinder token) {
12821         synchronized (this) {
12822             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12823             if (r == null) {
12824                 throw new IllegalArgumentException();
12825             }
12826             return r.task.getTopActivity() == r;
12827         }
12828     }
12829
12830     @Override
12831     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12832         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12833             String msg = "Permission Denial: setHasTopUi() from pid="
12834                     + Binder.getCallingPid()
12835                     + ", uid=" + Binder.getCallingUid()
12836                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12837             Slog.w(TAG, msg);
12838             throw new SecurityException(msg);
12839         }
12840         final int pid = Binder.getCallingPid();
12841         final long origId = Binder.clearCallingIdentity();
12842         try {
12843             synchronized (this) {
12844                 boolean changed = false;
12845                 ProcessRecord pr;
12846                 synchronized (mPidsSelfLocked) {
12847                     pr = mPidsSelfLocked.get(pid);
12848                     if (pr == null) {
12849                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12850                         return;
12851                     }
12852                     if (pr.hasTopUi != hasTopUi) {
12853                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12854                         pr.hasTopUi = hasTopUi;
12855                         changed = true;
12856                     }
12857                 }
12858                 if (changed) {
12859                     updateOomAdjLocked(pr);
12860                 }
12861             }
12862         } finally {
12863             Binder.restoreCallingIdentity(origId);
12864         }
12865     }
12866
12867     public final void enterSafeMode() {
12868         synchronized(this) {
12869             // It only makes sense to do this before the system is ready
12870             // and started launching other packages.
12871             if (!mSystemReady) {
12872                 try {
12873                     AppGlobals.getPackageManager().enterSafeMode();
12874                 } catch (RemoteException e) {
12875                 }
12876             }
12877
12878             mSafeMode = true;
12879         }
12880     }
12881
12882     public final void showSafeModeOverlay() {
12883         View v = LayoutInflater.from(mContext).inflate(
12884                 com.android.internal.R.layout.safe_mode, null);
12885         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12886         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12887         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12888         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12889         lp.gravity = Gravity.BOTTOM | Gravity.START;
12890         lp.format = v.getBackground().getOpacity();
12891         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12892                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12893         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12894         ((WindowManager)mContext.getSystemService(
12895                 Context.WINDOW_SERVICE)).addView(v, lp);
12896     }
12897
12898     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12899         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12900             return;
12901         }
12902         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12903         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12904         synchronized (stats) {
12905             if (mBatteryStatsService.isOnBattery()) {
12906                 mBatteryStatsService.enforceCallingPermission();
12907                 int MY_UID = Binder.getCallingUid();
12908                 final int uid;
12909                 if (sender == null) {
12910                     uid = sourceUid;
12911                 } else {
12912                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12913                 }
12914                 BatteryStatsImpl.Uid.Pkg pkg =
12915                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12916                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12917                 pkg.noteWakeupAlarmLocked(tag);
12918             }
12919         }
12920     }
12921
12922     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12923         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12924             return;
12925         }
12926         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12927         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12928         synchronized (stats) {
12929             mBatteryStatsService.enforceCallingPermission();
12930             int MY_UID = Binder.getCallingUid();
12931             final int uid;
12932             if (sender == null) {
12933                 uid = sourceUid;
12934             } else {
12935                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12936             }
12937             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12938         }
12939     }
12940
12941     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12942         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12943             return;
12944         }
12945         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12946         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12947         synchronized (stats) {
12948             mBatteryStatsService.enforceCallingPermission();
12949             int MY_UID = Binder.getCallingUid();
12950             final int uid;
12951             if (sender == null) {
12952                 uid = sourceUid;
12953             } else {
12954                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12955             }
12956             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12957         }
12958     }
12959
12960     public boolean killPids(int[] pids, String pReason, boolean secure) {
12961         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12962             throw new SecurityException("killPids only available to the system");
12963         }
12964         String reason = (pReason == null) ? "Unknown" : pReason;
12965         // XXX Note: don't acquire main activity lock here, because the window
12966         // manager calls in with its locks held.
12967
12968         boolean killed = false;
12969         synchronized (mPidsSelfLocked) {
12970             int worstType = 0;
12971             for (int i=0; i<pids.length; i++) {
12972                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12973                 if (proc != null) {
12974                     int type = proc.setAdj;
12975                     if (type > worstType) {
12976                         worstType = type;
12977                     }
12978                 }
12979             }
12980
12981             // If the worst oom_adj is somewhere in the cached proc LRU range,
12982             // then constrain it so we will kill all cached procs.
12983             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12984                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12985                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12986             }
12987
12988             // If this is not a secure call, don't let it kill processes that
12989             // are important.
12990             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12991                 worstType = ProcessList.SERVICE_ADJ;
12992             }
12993
12994             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12995             for (int i=0; i<pids.length; i++) {
12996                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12997                 if (proc == null) {
12998                     continue;
12999                 }
13000                 int adj = proc.setAdj;
13001                 if (adj >= worstType && !proc.killedByAm) {
13002                     proc.kill(reason, true);
13003                     killed = true;
13004                 }
13005             }
13006         }
13007         return killed;
13008     }
13009
13010     @Override
13011     public void killUid(int appId, int userId, String reason) {
13012         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13013         synchronized (this) {
13014             final long identity = Binder.clearCallingIdentity();
13015             try {
13016                 killPackageProcessesLocked(null, appId, userId,
13017                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13018                         reason != null ? reason : "kill uid");
13019             } finally {
13020                 Binder.restoreCallingIdentity(identity);
13021             }
13022         }
13023     }
13024
13025     @Override
13026     public boolean killProcessesBelowForeground(String reason) {
13027         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13028             throw new SecurityException("killProcessesBelowForeground() only available to system");
13029         }
13030
13031         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13032     }
13033
13034     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13035         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13036             throw new SecurityException("killProcessesBelowAdj() only available to system");
13037         }
13038
13039         boolean killed = false;
13040         synchronized (mPidsSelfLocked) {
13041             final int size = mPidsSelfLocked.size();
13042             for (int i = 0; i < size; i++) {
13043                 final int pid = mPidsSelfLocked.keyAt(i);
13044                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13045                 if (proc == null) continue;
13046
13047                 final int adj = proc.setAdj;
13048                 if (adj > belowAdj && !proc.killedByAm) {
13049                     proc.kill(reason, true);
13050                     killed = true;
13051                 }
13052             }
13053         }
13054         return killed;
13055     }
13056
13057     @Override
13058     public void hang(final IBinder who, boolean allowRestart) {
13059         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13060                 != PackageManager.PERMISSION_GRANTED) {
13061             throw new SecurityException("Requires permission "
13062                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13063         }
13064
13065         final IBinder.DeathRecipient death = new DeathRecipient() {
13066             @Override
13067             public void binderDied() {
13068                 synchronized (this) {
13069                     notifyAll();
13070                 }
13071             }
13072         };
13073
13074         try {
13075             who.linkToDeath(death, 0);
13076         } catch (RemoteException e) {
13077             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13078             return;
13079         }
13080
13081         synchronized (this) {
13082             Watchdog.getInstance().setAllowRestart(allowRestart);
13083             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13084             synchronized (death) {
13085                 while (who.isBinderAlive()) {
13086                     try {
13087                         death.wait();
13088                     } catch (InterruptedException e) {
13089                     }
13090                 }
13091             }
13092             Watchdog.getInstance().setAllowRestart(true);
13093         }
13094     }
13095
13096     @Override
13097     public void restart() {
13098         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13099                 != PackageManager.PERMISSION_GRANTED) {
13100             throw new SecurityException("Requires permission "
13101                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13102         }
13103
13104         Log.i(TAG, "Sending shutdown broadcast...");
13105
13106         BroadcastReceiver br = new BroadcastReceiver() {
13107             @Override public void onReceive(Context context, Intent intent) {
13108                 // Now the broadcast is done, finish up the low-level shutdown.
13109                 Log.i(TAG, "Shutting down activity manager...");
13110                 shutdown(10000);
13111                 Log.i(TAG, "Shutdown complete, restarting!");
13112                 Process.killProcess(Process.myPid());
13113                 System.exit(10);
13114             }
13115         };
13116
13117         // First send the high-level shut down broadcast.
13118         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13119         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13120         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13121         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13122         mContext.sendOrderedBroadcastAsUser(intent,
13123                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13124         */
13125         br.onReceive(mContext, intent);
13126     }
13127
13128     private long getLowRamTimeSinceIdle(long now) {
13129         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13130     }
13131
13132     @Override
13133     public void performIdleMaintenance() {
13134         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13135                 != PackageManager.PERMISSION_GRANTED) {
13136             throw new SecurityException("Requires permission "
13137                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13138         }
13139
13140         synchronized (this) {
13141             final long now = SystemClock.uptimeMillis();
13142             final long timeSinceLastIdle = now - mLastIdleTime;
13143             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13144             mLastIdleTime = now;
13145             mLowRamTimeSinceLastIdle = 0;
13146             if (mLowRamStartTime != 0) {
13147                 mLowRamStartTime = now;
13148             }
13149
13150             StringBuilder sb = new StringBuilder(128);
13151             sb.append("Idle maintenance over ");
13152             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13153             sb.append(" low RAM for ");
13154             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13155             Slog.i(TAG, sb.toString());
13156
13157             // If at least 1/3 of our time since the last idle period has been spent
13158             // with RAM low, then we want to kill processes.
13159             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13160
13161             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13162                 ProcessRecord proc = mLruProcesses.get(i);
13163                 if (proc.notCachedSinceIdle) {
13164                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13165                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13166                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13167                         if (doKilling && proc.initialIdlePss != 0
13168                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13169                             sb = new StringBuilder(128);
13170                             sb.append("Kill");
13171                             sb.append(proc.processName);
13172                             sb.append(" in idle maint: pss=");
13173                             sb.append(proc.lastPss);
13174                             sb.append(", swapPss=");
13175                             sb.append(proc.lastSwapPss);
13176                             sb.append(", initialPss=");
13177                             sb.append(proc.initialIdlePss);
13178                             sb.append(", period=");
13179                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13180                             sb.append(", lowRamPeriod=");
13181                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13182                             Slog.wtfQuiet(TAG, sb.toString());
13183                             proc.kill("idle maint (pss " + proc.lastPss
13184                                     + " from " + proc.initialIdlePss + ")", true);
13185                         }
13186                     }
13187                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13188                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13189                     proc.notCachedSinceIdle = true;
13190                     proc.initialIdlePss = 0;
13191                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13192                             mTestPssMode, isSleepingLocked(), now);
13193                 }
13194             }
13195
13196             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13197             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13198         }
13199     }
13200
13201     @Override
13202     public void sendIdleJobTrigger() {
13203         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13204                 != PackageManager.PERMISSION_GRANTED) {
13205             throw new SecurityException("Requires permission "
13206                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13207         }
13208
13209         final long ident = Binder.clearCallingIdentity();
13210         try {
13211             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13212                     .setPackage("android")
13213                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13214             broadcastIntent(null, intent, null, null, 0, null, null, null,
13215                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13216         } finally {
13217             Binder.restoreCallingIdentity(ident);
13218         }
13219     }
13220
13221     private void retrieveSettings() {
13222         final ContentResolver resolver = mContext.getContentResolver();
13223         final boolean freeformWindowManagement =
13224                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13225                         || Settings.Global.getInt(
13226                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13227         final boolean supportsPictureInPicture =
13228                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13229
13230         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13231         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13232         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13233         final boolean alwaysFinishActivities =
13234                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13235         final boolean lenientBackgroundCheck =
13236                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13237         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13238         final boolean forceResizable = Settings.Global.getInt(
13239                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13240         final boolean supportsLeanbackOnly =
13241                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13242
13243         // Transfer any global setting for forcing RTL layout, into a System Property
13244         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13245
13246         final Configuration configuration = new Configuration();
13247         Settings.System.getConfiguration(resolver, configuration);
13248         if (forceRtl) {
13249             // This will take care of setting the correct layout direction flags
13250             configuration.setLayoutDirection(configuration.locale);
13251         }
13252
13253         synchronized (this) {
13254             mDebugApp = mOrigDebugApp = debugApp;
13255             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13256             mAlwaysFinishActivities = alwaysFinishActivities;
13257             mLenientBackgroundCheck = lenientBackgroundCheck;
13258             mSupportsLeanbackOnly = supportsLeanbackOnly;
13259             mForceResizableActivities = forceResizable;
13260             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13261             if (supportsMultiWindow || forceResizable) {
13262                 mSupportsMultiWindow = true;
13263                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13264                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13265             } else {
13266                 mSupportsMultiWindow = false;
13267                 mSupportsFreeformWindowManagement = false;
13268                 mSupportsPictureInPicture = false;
13269             }
13270             // This happens before any activities are started, so we can
13271             // change mConfiguration in-place.
13272             updateConfigurationLocked(configuration, null, true);
13273             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13274                     "Initial config: " + mConfiguration);
13275
13276             // Load resources only after the current configuration has been set.
13277             final Resources res = mContext.getResources();
13278             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13279             mThumbnailWidth = res.getDimensionPixelSize(
13280                     com.android.internal.R.dimen.thumbnail_width);
13281             mThumbnailHeight = res.getDimensionPixelSize(
13282                     com.android.internal.R.dimen.thumbnail_height);
13283             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13284                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13285             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13286                     com.android.internal.R.string.config_appsNotReportingCrashes));
13287             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13288                 mFullscreenThumbnailScale = (float) res
13289                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13290                     (float) mConfiguration.screenWidthDp;
13291             } else {
13292                 mFullscreenThumbnailScale = res.getFraction(
13293                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13294             }
13295         }
13296     }
13297
13298     public boolean testIsSystemReady() {
13299         // no need to synchronize(this) just to read & return the value
13300         return mSystemReady;
13301     }
13302
13303     public void systemReady(final Runnable goingCallback) {
13304         synchronized(this) {
13305             if (mSystemReady) {
13306                 // If we're done calling all the receivers, run the next "boot phase" passed in
13307                 // by the SystemServer
13308                 if (goingCallback != null) {
13309                     goingCallback.run();
13310                 }
13311                 return;
13312             }
13313
13314             mLocalDeviceIdleController
13315                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13316
13317             // Make sure we have the current profile info, since it is needed for security checks.
13318             mUserController.onSystemReady();
13319             mRecentTasks.onSystemReadyLocked();
13320             mAppOpsService.systemReady();
13321             mSystemReady = true;
13322         }
13323
13324         ArrayList<ProcessRecord> procsToKill = null;
13325         synchronized(mPidsSelfLocked) {
13326             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13327                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13328                 if (!isAllowedWhileBooting(proc.info)){
13329                     if (procsToKill == null) {
13330                         procsToKill = new ArrayList<ProcessRecord>();
13331                     }
13332                     procsToKill.add(proc);
13333                 }
13334             }
13335         }
13336
13337         synchronized(this) {
13338             if (procsToKill != null) {
13339                 for (int i=procsToKill.size()-1; i>=0; i--) {
13340                     ProcessRecord proc = procsToKill.get(i);
13341                     Slog.i(TAG, "Removing system update proc: " + proc);
13342                     removeProcessLocked(proc, true, false, "system update done");
13343                 }
13344             }
13345
13346             // Now that we have cleaned up any update processes, we
13347             // are ready to start launching real processes and know that
13348             // we won't trample on them any more.
13349             mProcessesReady = true;
13350         }
13351
13352         Slog.i(TAG, "System now ready");
13353         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13354             SystemClock.uptimeMillis());
13355
13356         synchronized(this) {
13357             // Make sure we have no pre-ready processes sitting around.
13358
13359             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13360                 ResolveInfo ri = mContext.getPackageManager()
13361                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13362                                 STOCK_PM_FLAGS);
13363                 CharSequence errorMsg = null;
13364                 if (ri != null) {
13365                     ActivityInfo ai = ri.activityInfo;
13366                     ApplicationInfo app = ai.applicationInfo;
13367                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13368                         mTopAction = Intent.ACTION_FACTORY_TEST;
13369                         mTopData = null;
13370                         mTopComponent = new ComponentName(app.packageName,
13371                                 ai.name);
13372                     } else {
13373                         errorMsg = mContext.getResources().getText(
13374                                 com.android.internal.R.string.factorytest_not_system);
13375                     }
13376                 } else {
13377                     errorMsg = mContext.getResources().getText(
13378                             com.android.internal.R.string.factorytest_no_action);
13379                 }
13380                 if (errorMsg != null) {
13381                     mTopAction = null;
13382                     mTopData = null;
13383                     mTopComponent = null;
13384                     Message msg = Message.obtain();
13385                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13386                     msg.getData().putCharSequence("msg", errorMsg);
13387                     mUiHandler.sendMessage(msg);
13388                 }
13389             }
13390         }
13391
13392         retrieveSettings();
13393         final int currentUserId;
13394         synchronized (this) {
13395             currentUserId = mUserController.getCurrentUserIdLocked();
13396             readGrantedUriPermissionsLocked();
13397         }
13398
13399         if (goingCallback != null) goingCallback.run();
13400
13401         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13402                 Integer.toString(currentUserId), currentUserId);
13403         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13404                 Integer.toString(currentUserId), currentUserId);
13405         mSystemServiceManager.startUser(currentUserId);
13406
13407         synchronized (this) {
13408             // Only start up encryption-aware persistent apps; once user is
13409             // unlocked we'll come back around and start unaware apps
13410             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13411
13412             // Start up initial activity.
13413             mBooting = true;
13414             // Enable home activity for system user, so that the system can always boot
13415             if (UserManager.isSplitSystemUser()) {
13416                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13417                 try {
13418                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13419                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13420                             UserHandle.USER_SYSTEM);
13421                 } catch (RemoteException e) {
13422                     throw e.rethrowAsRuntimeException();
13423                 }
13424             }
13425             startHomeActivityLocked(currentUserId, "systemReady");
13426
13427             try {
13428                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13429                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13430                             + " data partition or your device will be unstable.");
13431                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13432                 }
13433             } catch (RemoteException e) {
13434             }
13435
13436             if (!Build.isBuildConsistent()) {
13437                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13438                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13439             }
13440
13441             long ident = Binder.clearCallingIdentity();
13442             try {
13443                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13444                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13445                         | Intent.FLAG_RECEIVER_FOREGROUND);
13446                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13447                 broadcastIntentLocked(null, null, intent,
13448                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13449                         null, false, false, MY_PID, Process.SYSTEM_UID,
13450                         currentUserId);
13451                 intent = new Intent(Intent.ACTION_USER_STARTING);
13452                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13453                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13454                 broadcastIntentLocked(null, null, intent,
13455                         null, new IIntentReceiver.Stub() {
13456                             @Override
13457                             public void performReceive(Intent intent, int resultCode, String data,
13458                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13459                                     throws RemoteException {
13460                             }
13461                         }, 0, null, null,
13462                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13463                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13464             } catch (Throwable t) {
13465                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13466             } finally {
13467                 Binder.restoreCallingIdentity(ident);
13468             }
13469             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13470             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13471         }
13472     }
13473
13474     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13475         synchronized (this) {
13476             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13477         }
13478     }
13479
13480     void skipCurrentReceiverLocked(ProcessRecord app) {
13481         for (BroadcastQueue queue : mBroadcastQueues) {
13482             queue.skipCurrentReceiverLocked(app);
13483         }
13484     }
13485
13486     /**
13487      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13488      * The application process will exit immediately after this call returns.
13489      * @param app object of the crashing app, null for the system server
13490      * @param crashInfo describing the exception
13491      */
13492     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13493         ProcessRecord r = findAppProcess(app, "Crash");
13494         final String processName = app == null ? "system_server"
13495                 : (r == null ? "unknown" : r.processName);
13496
13497         handleApplicationCrashInner("crash", r, processName, crashInfo);
13498     }
13499
13500     /* Native crash reporting uses this inner version because it needs to be somewhat
13501      * decoupled from the AM-managed cleanup lifecycle
13502      */
13503     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13504             ApplicationErrorReport.CrashInfo crashInfo) {
13505         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13506                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13507                 r == null ? -1 : r.info.flags,
13508                 crashInfo.exceptionClassName,
13509                 crashInfo.exceptionMessage,
13510                 crashInfo.throwFileName,
13511                 crashInfo.throwLineNumber);
13512
13513         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13514
13515         mAppErrors.crashApplication(r, crashInfo);
13516     }
13517
13518     public void handleApplicationStrictModeViolation(
13519             IBinder app,
13520             int violationMask,
13521             StrictMode.ViolationInfo info) {
13522         ProcessRecord r = findAppProcess(app, "StrictMode");
13523         if (r == null) {
13524             return;
13525         }
13526
13527         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13528             Integer stackFingerprint = info.hashCode();
13529             boolean logIt = true;
13530             synchronized (mAlreadyLoggedViolatedStacks) {
13531                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13532                     logIt = false;
13533                     // TODO: sub-sample into EventLog for these, with
13534                     // the info.durationMillis?  Then we'd get
13535                     // the relative pain numbers, without logging all
13536                     // the stack traces repeatedly.  We'd want to do
13537                     // likewise in the client code, which also does
13538                     // dup suppression, before the Binder call.
13539                 } else {
13540                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13541                         mAlreadyLoggedViolatedStacks.clear();
13542                     }
13543                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13544                 }
13545             }
13546             if (logIt) {
13547                 logStrictModeViolationToDropBox(r, info);
13548             }
13549         }
13550
13551         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13552             AppErrorResult result = new AppErrorResult();
13553             synchronized (this) {
13554                 final long origId = Binder.clearCallingIdentity();
13555
13556                 Message msg = Message.obtain();
13557                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13558                 HashMap<String, Object> data = new HashMap<String, Object>();
13559                 data.put("result", result);
13560                 data.put("app", r);
13561                 data.put("violationMask", violationMask);
13562                 data.put("info", info);
13563                 msg.obj = data;
13564                 mUiHandler.sendMessage(msg);
13565
13566                 Binder.restoreCallingIdentity(origId);
13567             }
13568             int res = result.get();
13569             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13570         }
13571     }
13572
13573     // Depending on the policy in effect, there could be a bunch of
13574     // these in quick succession so we try to batch these together to
13575     // minimize disk writes, number of dropbox entries, and maximize
13576     // compression, by having more fewer, larger records.
13577     private void logStrictModeViolationToDropBox(
13578             ProcessRecord process,
13579             StrictMode.ViolationInfo info) {
13580         if (info == null) {
13581             return;
13582         }
13583         final boolean isSystemApp = process == null ||
13584                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13585                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13586         final String processName = process == null ? "unknown" : process.processName;
13587         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13588         final DropBoxManager dbox = (DropBoxManager)
13589                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13590
13591         // Exit early if the dropbox isn't configured to accept this report type.
13592         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13593
13594         boolean bufferWasEmpty;
13595         boolean needsFlush;
13596         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13597         synchronized (sb) {
13598             bufferWasEmpty = sb.length() == 0;
13599             appendDropBoxProcessHeaders(process, processName, sb);
13600             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13601             sb.append("System-App: ").append(isSystemApp).append("\n");
13602             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13603             if (info.violationNumThisLoop != 0) {
13604                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13605             }
13606             if (info.numAnimationsRunning != 0) {
13607                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13608             }
13609             if (info.broadcastIntentAction != null) {
13610                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13611             }
13612             if (info.durationMillis != -1) {
13613                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13614             }
13615             if (info.numInstances != -1) {
13616                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13617             }
13618             if (info.tags != null) {
13619                 for (String tag : info.tags) {
13620                     sb.append("Span-Tag: ").append(tag).append("\n");
13621                 }
13622             }
13623             sb.append("\n");
13624             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13625                 sb.append(info.crashInfo.stackTrace);
13626                 sb.append("\n");
13627             }
13628             if (info.message != null) {
13629                 sb.append(info.message);
13630                 sb.append("\n");
13631             }
13632
13633             // Only buffer up to ~64k.  Various logging bits truncate
13634             // things at 128k.
13635             needsFlush = (sb.length() > 64 * 1024);
13636         }
13637
13638         // Flush immediately if the buffer's grown too large, or this
13639         // is a non-system app.  Non-system apps are isolated with a
13640         // different tag & policy and not batched.
13641         //
13642         // Batching is useful during internal testing with
13643         // StrictMode settings turned up high.  Without batching,
13644         // thousands of separate files could be created on boot.
13645         if (!isSystemApp || needsFlush) {
13646             new Thread("Error dump: " + dropboxTag) {
13647                 @Override
13648                 public void run() {
13649                     String report;
13650                     synchronized (sb) {
13651                         report = sb.toString();
13652                         sb.delete(0, sb.length());
13653                         sb.trimToSize();
13654                     }
13655                     if (report.length() != 0) {
13656                         dbox.addText(dropboxTag, report);
13657                     }
13658                 }
13659             }.start();
13660             return;
13661         }
13662
13663         // System app batching:
13664         if (!bufferWasEmpty) {
13665             // An existing dropbox-writing thread is outstanding, so
13666             // we don't need to start it up.  The existing thread will
13667             // catch the buffer appends we just did.
13668             return;
13669         }
13670
13671         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13672         // (After this point, we shouldn't access AMS internal data structures.)
13673         new Thread("Error dump: " + dropboxTag) {
13674             @Override
13675             public void run() {
13676                 // 5 second sleep to let stacks arrive and be batched together
13677                 try {
13678                     Thread.sleep(5000);  // 5 seconds
13679                 } catch (InterruptedException e) {}
13680
13681                 String errorReport;
13682                 synchronized (mStrictModeBuffer) {
13683                     errorReport = mStrictModeBuffer.toString();
13684                     if (errorReport.length() == 0) {
13685                         return;
13686                     }
13687                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13688                     mStrictModeBuffer.trimToSize();
13689                 }
13690                 dbox.addText(dropboxTag, errorReport);
13691             }
13692         }.start();
13693     }
13694
13695     /**
13696      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13697      * @param app object of the crashing app, null for the system server
13698      * @param tag reported by the caller
13699      * @param system whether this wtf is coming from the system
13700      * @param crashInfo describing the context of the error
13701      * @return true if the process should exit immediately (WTF is fatal)
13702      */
13703     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13704             final ApplicationErrorReport.CrashInfo crashInfo) {
13705         final int callingUid = Binder.getCallingUid();
13706         final int callingPid = Binder.getCallingPid();
13707
13708         if (system) {
13709             // If this is coming from the system, we could very well have low-level
13710             // system locks held, so we want to do this all asynchronously.  And we
13711             // never want this to become fatal, so there is that too.
13712             mHandler.post(new Runnable() {
13713                 @Override public void run() {
13714                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13715                 }
13716             });
13717             return false;
13718         }
13719
13720         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13721                 crashInfo);
13722
13723         if (r != null && r.pid != Process.myPid() &&
13724                 Settings.Global.getInt(mContext.getContentResolver(),
13725                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13726             mAppErrors.crashApplication(r, crashInfo);
13727             return true;
13728         } else {
13729             return false;
13730         }
13731     }
13732
13733     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13734             final ApplicationErrorReport.CrashInfo crashInfo) {
13735         final ProcessRecord r = findAppProcess(app, "WTF");
13736         final String processName = app == null ? "system_server"
13737                 : (r == null ? "unknown" : r.processName);
13738
13739         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13740                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13741
13742         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13743
13744         return r;
13745     }
13746
13747     /**
13748      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13749      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13750      */
13751     private ProcessRecord findAppProcess(IBinder app, String reason) {
13752         if (app == null) {
13753             return null;
13754         }
13755
13756         synchronized (this) {
13757             final int NP = mProcessNames.getMap().size();
13758             for (int ip=0; ip<NP; ip++) {
13759                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13760                 final int NA = apps.size();
13761                 for (int ia=0; ia<NA; ia++) {
13762                     ProcessRecord p = apps.valueAt(ia);
13763                     if (p.thread != null && p.thread.asBinder() == app) {
13764                         return p;
13765                     }
13766                 }
13767             }
13768
13769             Slog.w(TAG, "Can't find mystery application for " + reason
13770                     + " from pid=" + Binder.getCallingPid()
13771                     + " uid=" + Binder.getCallingUid() + ": " + app);
13772             return null;
13773         }
13774     }
13775
13776     /**
13777      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13778      * to append various headers to the dropbox log text.
13779      */
13780     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13781             StringBuilder sb) {
13782         // Watchdog thread ends up invoking this function (with
13783         // a null ProcessRecord) to add the stack file to dropbox.
13784         // Do not acquire a lock on this (am) in such cases, as it
13785         // could cause a potential deadlock, if and when watchdog
13786         // is invoked due to unavailability of lock on am and it
13787         // would prevent watchdog from killing system_server.
13788         if (process == null) {
13789             sb.append("Process: ").append(processName).append("\n");
13790             return;
13791         }
13792         // Note: ProcessRecord 'process' is guarded by the service
13793         // instance.  (notably process.pkgList, which could otherwise change
13794         // concurrently during execution of this method)
13795         synchronized (this) {
13796             sb.append("Process: ").append(processName).append("\n");
13797             int flags = process.info.flags;
13798             IPackageManager pm = AppGlobals.getPackageManager();
13799             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13800             for (int ip=0; ip<process.pkgList.size(); ip++) {
13801                 String pkg = process.pkgList.keyAt(ip);
13802                 sb.append("Package: ").append(pkg);
13803                 try {
13804                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13805                     if (pi != null) {
13806                         sb.append(" v").append(pi.versionCode);
13807                         if (pi.versionName != null) {
13808                             sb.append(" (").append(pi.versionName).append(")");
13809                         }
13810                     }
13811                 } catch (RemoteException e) {
13812                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13813                 }
13814                 sb.append("\n");
13815             }
13816         }
13817     }
13818
13819     private static String processClass(ProcessRecord process) {
13820         if (process == null || process.pid == MY_PID) {
13821             return "system_server";
13822         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13823             return "system_app";
13824         } else {
13825             return "data_app";
13826         }
13827     }
13828
13829     private volatile long mWtfClusterStart;
13830     private volatile int mWtfClusterCount;
13831
13832     /**
13833      * Write a description of an error (crash, WTF, ANR) to the drop box.
13834      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13835      * @param process which caused the error, null means the system server
13836      * @param activity which triggered the error, null if unknown
13837      * @param parent activity related to the error, null if unknown
13838      * @param subject line related to the error, null if absent
13839      * @param report in long form describing the error, null if absent
13840      * @param dataFile text file to include in the report, null if none
13841      * @param crashInfo giving an application stack trace, null if absent
13842      */
13843     public void addErrorToDropBox(String eventType,
13844             ProcessRecord process, String processName, ActivityRecord activity,
13845             ActivityRecord parent, String subject,
13846             final String report, final File dataFile,
13847             final ApplicationErrorReport.CrashInfo crashInfo) {
13848         // NOTE -- this must never acquire the ActivityManagerService lock,
13849         // otherwise the watchdog may be prevented from resetting the system.
13850
13851         final String dropboxTag = processClass(process) + "_" + eventType;
13852         final DropBoxManager dbox = (DropBoxManager)
13853                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13854
13855         // Exit early if the dropbox isn't configured to accept this report type.
13856         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13857
13858         // Rate-limit how often we're willing to do the heavy lifting below to
13859         // collect and record logs; currently 5 logs per 10 second period.
13860         final long now = SystemClock.elapsedRealtime();
13861         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13862             mWtfClusterStart = now;
13863             mWtfClusterCount = 1;
13864         } else {
13865             if (mWtfClusterCount++ >= 5) return;
13866         }
13867
13868         final StringBuilder sb = new StringBuilder(1024);
13869         appendDropBoxProcessHeaders(process, processName, sb);
13870         if (process != null) {
13871             sb.append("Foreground: ")
13872                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13873                     .append("\n");
13874         }
13875         if (activity != null) {
13876             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13877         }
13878         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13879             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13880         }
13881         if (parent != null && parent != activity) {
13882             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13883         }
13884         if (subject != null) {
13885             sb.append("Subject: ").append(subject).append("\n");
13886         }
13887         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13888         if (Debug.isDebuggerConnected()) {
13889             sb.append("Debugger: Connected\n");
13890         }
13891         sb.append("\n");
13892
13893         // Do the rest in a worker thread to avoid blocking the caller on I/O
13894         // (After this point, we shouldn't access AMS internal data structures.)
13895         Thread worker = new Thread("Error dump: " + dropboxTag) {
13896             @Override
13897             public void run() {
13898                 if (report != null) {
13899                     sb.append(report);
13900                 }
13901
13902                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13903                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13904                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13905                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13906
13907                 if (dataFile != null && maxDataFileSize > 0) {
13908                     try {
13909                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13910                                     "\n\n[[TRUNCATED]]"));
13911                     } catch (IOException e) {
13912                         Slog.e(TAG, "Error reading " + dataFile, e);
13913                     }
13914                 }
13915                 if (crashInfo != null && crashInfo.stackTrace != null) {
13916                     sb.append(crashInfo.stackTrace);
13917                 }
13918
13919                 if (lines > 0) {
13920                     sb.append("\n");
13921
13922                     // Merge several logcat streams, and take the last N lines
13923                     InputStreamReader input = null;
13924                     try {
13925                         java.lang.Process logcat = new ProcessBuilder(
13926                                 "/system/bin/timeout", "-k", "15s", "10s",
13927                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13928                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13929                                         .redirectErrorStream(true).start();
13930
13931                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13932                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13933                         input = new InputStreamReader(logcat.getInputStream());
13934
13935                         int num;
13936                         char[] buf = new char[8192];
13937                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13938                     } catch (IOException e) {
13939                         Slog.e(TAG, "Error running logcat", e);
13940                     } finally {
13941                         if (input != null) try { input.close(); } catch (IOException e) {}
13942                     }
13943                 }
13944
13945                 dbox.addText(dropboxTag, sb.toString());
13946             }
13947         };
13948
13949         if (process == null) {
13950             // If process is null, we are being called from some internal code
13951             // and may be about to die -- run this synchronously.
13952             worker.run();
13953         } else {
13954             worker.start();
13955         }
13956     }
13957
13958     @Override
13959     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13960         enforceNotIsolatedCaller("getProcessesInErrorState");
13961         // assume our apps are happy - lazy create the list
13962         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13963
13964         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13965                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13966         int userId = UserHandle.getUserId(Binder.getCallingUid());
13967
13968         synchronized (this) {
13969
13970             // iterate across all processes
13971             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13972                 ProcessRecord app = mLruProcesses.get(i);
13973                 if (!allUsers && app.userId != userId) {
13974                     continue;
13975                 }
13976                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13977                     // This one's in trouble, so we'll generate a report for it
13978                     // crashes are higher priority (in case there's a crash *and* an anr)
13979                     ActivityManager.ProcessErrorStateInfo report = null;
13980                     if (app.crashing) {
13981                         report = app.crashingReport;
13982                     } else if (app.notResponding) {
13983                         report = app.notRespondingReport;
13984                     }
13985
13986                     if (report != null) {
13987                         if (errList == null) {
13988                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13989                         }
13990                         errList.add(report);
13991                     } else {
13992                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13993                                 " crashing = " + app.crashing +
13994                                 " notResponding = " + app.notResponding);
13995                     }
13996                 }
13997             }
13998         }
13999
14000         return errList;
14001     }
14002
14003     static int procStateToImportance(int procState, int memAdj,
14004             ActivityManager.RunningAppProcessInfo currApp) {
14005         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14006         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14007             currApp.lru = memAdj;
14008         } else {
14009             currApp.lru = 0;
14010         }
14011         return imp;
14012     }
14013
14014     private void fillInProcMemInfo(ProcessRecord app,
14015             ActivityManager.RunningAppProcessInfo outInfo) {
14016         outInfo.pid = app.pid;
14017         outInfo.uid = app.info.uid;
14018         if (mHeavyWeightProcess == app) {
14019             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14020         }
14021         if (app.persistent) {
14022             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14023         }
14024         if (app.activities.size() > 0) {
14025             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14026         }
14027         outInfo.lastTrimLevel = app.trimMemoryLevel;
14028         int adj = app.curAdj;
14029         int procState = app.curProcState;
14030         outInfo.importance = procStateToImportance(procState, adj, outInfo);
14031         outInfo.importanceReasonCode = app.adjTypeCode;
14032         outInfo.processState = app.curProcState;
14033     }
14034
14035     @Override
14036     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14037         enforceNotIsolatedCaller("getRunningAppProcesses");
14038
14039         final int callingUid = Binder.getCallingUid();
14040
14041         // Lazy instantiation of list
14042         List<ActivityManager.RunningAppProcessInfo> runList = null;
14043         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14044                 callingUid) == PackageManager.PERMISSION_GRANTED;
14045         final int userId = UserHandle.getUserId(callingUid);
14046         final boolean allUids = isGetTasksAllowed(
14047                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14048
14049         synchronized (this) {
14050             // Iterate across all processes
14051             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14052                 ProcessRecord app = mLruProcesses.get(i);
14053                 if ((!allUsers && app.userId != userId)
14054                         || (!allUids && app.uid != callingUid)) {
14055                     continue;
14056                 }
14057                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14058                     // Generate process state info for running application
14059                     ActivityManager.RunningAppProcessInfo currApp =
14060                         new ActivityManager.RunningAppProcessInfo(app.processName,
14061                                 app.pid, app.getPackageList());
14062                     fillInProcMemInfo(app, currApp);
14063                     if (app.adjSource instanceof ProcessRecord) {
14064                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14065                         currApp.importanceReasonImportance =
14066                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14067                                         app.adjSourceProcState);
14068                     } else if (app.adjSource instanceof ActivityRecord) {
14069                         ActivityRecord r = (ActivityRecord)app.adjSource;
14070                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14071                     }
14072                     if (app.adjTarget instanceof ComponentName) {
14073                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14074                     }
14075                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14076                     //        + " lru=" + currApp.lru);
14077                     if (runList == null) {
14078                         runList = new ArrayList<>();
14079                     }
14080                     runList.add(currApp);
14081                 }
14082             }
14083         }
14084         return runList;
14085     }
14086
14087     @Override
14088     public List<ApplicationInfo> getRunningExternalApplications() {
14089         enforceNotIsolatedCaller("getRunningExternalApplications");
14090         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14091         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14092         if (runningApps != null && runningApps.size() > 0) {
14093             Set<String> extList = new HashSet<String>();
14094             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14095                 if (app.pkgList != null) {
14096                     for (String pkg : app.pkgList) {
14097                         extList.add(pkg);
14098                     }
14099                 }
14100             }
14101             IPackageManager pm = AppGlobals.getPackageManager();
14102             for (String pkg : extList) {
14103                 try {
14104                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14105                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14106                         retList.add(info);
14107                     }
14108                 } catch (RemoteException e) {
14109                 }
14110             }
14111         }
14112         return retList;
14113     }
14114
14115     @Override
14116     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14117         enforceNotIsolatedCaller("getMyMemoryState");
14118         synchronized (this) {
14119             ProcessRecord proc;
14120             synchronized (mPidsSelfLocked) {
14121                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14122             }
14123             fillInProcMemInfo(proc, outInfo);
14124         }
14125     }
14126
14127     @Override
14128     public int getMemoryTrimLevel() {
14129         enforceNotIsolatedCaller("getMyMemoryState");
14130         synchronized (this) {
14131             return mLastMemoryLevel;
14132         }
14133     }
14134
14135     @Override
14136     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14137             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14138         (new ActivityManagerShellCommand(this, false)).exec(
14139                 this, in, out, err, args, resultReceiver);
14140     }
14141
14142     @Override
14143     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14144         if (checkCallingPermission(android.Manifest.permission.DUMP)
14145                 != PackageManager.PERMISSION_GRANTED) {
14146             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14147                     + Binder.getCallingPid()
14148                     + ", uid=" + Binder.getCallingUid()
14149                     + " without permission "
14150                     + android.Manifest.permission.DUMP);
14151             return;
14152         }
14153
14154         boolean dumpAll = false;
14155         boolean dumpClient = false;
14156         boolean dumpCheckin = false;
14157         boolean dumpCheckinFormat = false;
14158         String dumpPackage = null;
14159
14160         int opti = 0;
14161         while (opti < args.length) {
14162             String opt = args[opti];
14163             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14164                 break;
14165             }
14166             opti++;
14167             if ("-a".equals(opt)) {
14168                 dumpAll = true;
14169             } else if ("-c".equals(opt)) {
14170                 dumpClient = true;
14171             } else if ("-p".equals(opt)) {
14172                 if (opti < args.length) {
14173                     dumpPackage = args[opti];
14174                     opti++;
14175                 } else {
14176                     pw.println("Error: -p option requires package argument");
14177                     return;
14178                 }
14179                 dumpClient = true;
14180             } else if ("--checkin".equals(opt)) {
14181                 dumpCheckin = dumpCheckinFormat = true;
14182             } else if ("-C".equals(opt)) {
14183                 dumpCheckinFormat = true;
14184             } else if ("-h".equals(opt)) {
14185                 ActivityManagerShellCommand.dumpHelp(pw, true);
14186                 return;
14187             } else {
14188                 pw.println("Unknown argument: " + opt + "; use -h for help");
14189             }
14190         }
14191
14192         long origId = Binder.clearCallingIdentity();
14193         boolean more = false;
14194         // Is the caller requesting to dump a particular piece of data?
14195         if (opti < args.length) {
14196             String cmd = args[opti];
14197             opti++;
14198             if ("activities".equals(cmd) || "a".equals(cmd)) {
14199                 synchronized (this) {
14200                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14201                 }
14202             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14203                 synchronized (this) {
14204                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14205                 }
14206             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14207                 String[] newArgs;
14208                 String name;
14209                 if (opti >= args.length) {
14210                     name = null;
14211                     newArgs = EMPTY_STRING_ARRAY;
14212                 } else {
14213                     dumpPackage = args[opti];
14214                     opti++;
14215                     newArgs = new String[args.length - opti];
14216                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14217                             args.length - opti);
14218                 }
14219                 synchronized (this) {
14220                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14221                 }
14222             } else if ("broadcast-stats".equals(cmd)) {
14223                 String[] newArgs;
14224                 String name;
14225                 if (opti >= args.length) {
14226                     name = null;
14227                     newArgs = EMPTY_STRING_ARRAY;
14228                 } else {
14229                     dumpPackage = args[opti];
14230                     opti++;
14231                     newArgs = new String[args.length - opti];
14232                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14233                             args.length - opti);
14234                 }
14235                 synchronized (this) {
14236                     if (dumpCheckinFormat) {
14237                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14238                                 dumpPackage);
14239                     } else {
14240                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14241                     }
14242                 }
14243             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14244                 String[] newArgs;
14245                 String name;
14246                 if (opti >= args.length) {
14247                     name = null;
14248                     newArgs = EMPTY_STRING_ARRAY;
14249                 } else {
14250                     dumpPackage = args[opti];
14251                     opti++;
14252                     newArgs = new String[args.length - opti];
14253                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14254                             args.length - opti);
14255                 }
14256                 synchronized (this) {
14257                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14258                 }
14259             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14260                 String[] newArgs;
14261                 String name;
14262                 if (opti >= args.length) {
14263                     name = null;
14264                     newArgs = EMPTY_STRING_ARRAY;
14265                 } else {
14266                     dumpPackage = args[opti];
14267                     opti++;
14268                     newArgs = new String[args.length - opti];
14269                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14270                             args.length - opti);
14271                 }
14272                 synchronized (this) {
14273                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14274                 }
14275             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14276                 synchronized (this) {
14277                     dumpOomLocked(fd, pw, args, opti, true);
14278                 }
14279             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14280                 synchronized (this) {
14281                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14282                 }
14283             } else if ("provider".equals(cmd)) {
14284                 String[] newArgs;
14285                 String name;
14286                 if (opti >= args.length) {
14287                     name = null;
14288                     newArgs = EMPTY_STRING_ARRAY;
14289                 } else {
14290                     name = args[opti];
14291                     opti++;
14292                     newArgs = new String[args.length - opti];
14293                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14294                 }
14295                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14296                     pw.println("No providers match: " + name);
14297                     pw.println("Use -h for help.");
14298                 }
14299             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14300                 synchronized (this) {
14301                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14302                 }
14303             } else if ("service".equals(cmd)) {
14304                 String[] newArgs;
14305                 String name;
14306                 if (opti >= args.length) {
14307                     name = null;
14308                     newArgs = EMPTY_STRING_ARRAY;
14309                 } else {
14310                     name = args[opti];
14311                     opti++;
14312                     newArgs = new String[args.length - opti];
14313                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14314                             args.length - opti);
14315                 }
14316                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14317                     pw.println("No services match: " + name);
14318                     pw.println("Use -h for help.");
14319                 }
14320             } else if ("package".equals(cmd)) {
14321                 String[] newArgs;
14322                 if (opti >= args.length) {
14323                     pw.println("package: no package name specified");
14324                     pw.println("Use -h for help.");
14325                 } else {
14326                     dumpPackage = args[opti];
14327                     opti++;
14328                     newArgs = new String[args.length - opti];
14329                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14330                             args.length - opti);
14331                     args = newArgs;
14332                     opti = 0;
14333                     more = true;
14334                 }
14335             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14336                 synchronized (this) {
14337                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14338                 }
14339             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14340                 if (dumpClient) {
14341                     ActiveServices.ServiceDumper dumper;
14342                     synchronized (this) {
14343                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14344                                 dumpPackage);
14345                     }
14346                     dumper.dumpWithClient();
14347                 } else {
14348                     synchronized (this) {
14349                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14350                                 dumpPackage).dumpLocked();
14351                     }
14352                 }
14353             } else if ("locks".equals(cmd)) {
14354                 LockGuard.dump(fd, pw, args);
14355             } else {
14356                 // Dumping a single activity?
14357                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14358                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14359                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14360                     if (res < 0) {
14361                         pw.println("Bad activity command, or no activities match: " + cmd);
14362                         pw.println("Use -h for help.");
14363                     }
14364                 }
14365             }
14366             if (!more) {
14367                 Binder.restoreCallingIdentity(origId);
14368                 return;
14369             }
14370         }
14371
14372         // No piece of data specified, dump everything.
14373         if (dumpCheckinFormat) {
14374             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14375         } else if (dumpClient) {
14376             ActiveServices.ServiceDumper sdumper;
14377             synchronized (this) {
14378                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14379                 pw.println();
14380                 if (dumpAll) {
14381                     pw.println("-------------------------------------------------------------------------------");
14382                 }
14383                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14384                 pw.println();
14385                 if (dumpAll) {
14386                     pw.println("-------------------------------------------------------------------------------");
14387                 }
14388                 if (dumpAll || dumpPackage != null) {
14389                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14390                     pw.println();
14391                     if (dumpAll) {
14392                         pw.println("-------------------------------------------------------------------------------");
14393                     }
14394                 }
14395                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14396                 pw.println();
14397                 if (dumpAll) {
14398                     pw.println("-------------------------------------------------------------------------------");
14399                 }
14400                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14401                 pw.println();
14402                 if (dumpAll) {
14403                     pw.println("-------------------------------------------------------------------------------");
14404                 }
14405                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14406                         dumpPackage);
14407             }
14408             sdumper.dumpWithClient();
14409             pw.println();
14410             synchronized (this) {
14411                 if (dumpAll) {
14412                     pw.println("-------------------------------------------------------------------------------");
14413                 }
14414                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14415                 pw.println();
14416                 if (dumpAll) {
14417                     pw.println("-------------------------------------------------------------------------------");
14418                 }
14419                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14420                 if (mAssociations.size() > 0) {
14421                     pw.println();
14422                     if (dumpAll) {
14423                         pw.println("-------------------------------------------------------------------------------");
14424                     }
14425                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14426                 }
14427                 pw.println();
14428                 if (dumpAll) {
14429                     pw.println("-------------------------------------------------------------------------------");
14430                 }
14431                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14432             }
14433
14434         } else {
14435             synchronized (this) {
14436                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14437                 pw.println();
14438                 if (dumpAll) {
14439                     pw.println("-------------------------------------------------------------------------------");
14440                 }
14441                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14442                 pw.println();
14443                 if (dumpAll) {
14444                     pw.println("-------------------------------------------------------------------------------");
14445                 }
14446                 if (dumpAll || dumpPackage != null) {
14447                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14448                     pw.println();
14449                     if (dumpAll) {
14450                         pw.println("-------------------------------------------------------------------------------");
14451                     }
14452                 }
14453                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14454                 pw.println();
14455                 if (dumpAll) {
14456                     pw.println("-------------------------------------------------------------------------------");
14457                 }
14458                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14459                 pw.println();
14460                 if (dumpAll) {
14461                     pw.println("-------------------------------------------------------------------------------");
14462                 }
14463                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14464                         .dumpLocked();
14465                 pw.println();
14466                 if (dumpAll) {
14467                     pw.println("-------------------------------------------------------------------------------");
14468                 }
14469                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14470                 pw.println();
14471                 if (dumpAll) {
14472                     pw.println("-------------------------------------------------------------------------------");
14473                 }
14474                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14475                 if (mAssociations.size() > 0) {
14476                     pw.println();
14477                     if (dumpAll) {
14478                         pw.println("-------------------------------------------------------------------------------");
14479                     }
14480                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14481                 }
14482                 pw.println();
14483                 if (dumpAll) {
14484                     pw.println("-------------------------------------------------------------------------------");
14485                 }
14486                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14487             }
14488         }
14489         Binder.restoreCallingIdentity(origId);
14490     }
14491
14492     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14493             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14494         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14495
14496         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14497                 dumpPackage);
14498         boolean needSep = printedAnything;
14499
14500         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14501                 dumpPackage, needSep, "  mFocusedActivity: ");
14502         if (printed) {
14503             printedAnything = true;
14504             needSep = false;
14505         }
14506
14507         if (dumpPackage == null) {
14508             if (needSep) {
14509                 pw.println();
14510             }
14511             needSep = true;
14512             printedAnything = true;
14513             mStackSupervisor.dump(pw, "  ");
14514         }
14515
14516         if (!printedAnything) {
14517             pw.println("  (nothing)");
14518         }
14519     }
14520
14521     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14522             int opti, boolean dumpAll, String dumpPackage) {
14523         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14524
14525         boolean printedAnything = false;
14526
14527         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14528             boolean printedHeader = false;
14529
14530             final int N = mRecentTasks.size();
14531             for (int i=0; i<N; i++) {
14532                 TaskRecord tr = mRecentTasks.get(i);
14533                 if (dumpPackage != null) {
14534                     if (tr.realActivity == null ||
14535                             !dumpPackage.equals(tr.realActivity)) {
14536                         continue;
14537                     }
14538                 }
14539                 if (!printedHeader) {
14540                     pw.println("  Recent tasks:");
14541                     printedHeader = true;
14542                     printedAnything = true;
14543                 }
14544                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14545                         pw.println(tr);
14546                 if (dumpAll) {
14547                     mRecentTasks.get(i).dump(pw, "    ");
14548                 }
14549             }
14550         }
14551
14552         if (!printedAnything) {
14553             pw.println("  (nothing)");
14554         }
14555     }
14556
14557     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14558             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14559         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14560
14561         int dumpUid = 0;
14562         if (dumpPackage != null) {
14563             IPackageManager pm = AppGlobals.getPackageManager();
14564             try {
14565                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14566             } catch (RemoteException e) {
14567             }
14568         }
14569
14570         boolean printedAnything = false;
14571
14572         final long now = SystemClock.uptimeMillis();
14573
14574         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14575             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14576                     = mAssociations.valueAt(i1);
14577             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14578                 SparseArray<ArrayMap<String, Association>> sourceUids
14579                         = targetComponents.valueAt(i2);
14580                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14581                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14582                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14583                         Association ass = sourceProcesses.valueAt(i4);
14584                         if (dumpPackage != null) {
14585                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14586                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14587                                 continue;
14588                             }
14589                         }
14590                         printedAnything = true;
14591                         pw.print("  ");
14592                         pw.print(ass.mTargetProcess);
14593                         pw.print("/");
14594                         UserHandle.formatUid(pw, ass.mTargetUid);
14595                         pw.print(" <- ");
14596                         pw.print(ass.mSourceProcess);
14597                         pw.print("/");
14598                         UserHandle.formatUid(pw, ass.mSourceUid);
14599                         pw.println();
14600                         pw.print("    via ");
14601                         pw.print(ass.mTargetComponent.flattenToShortString());
14602                         pw.println();
14603                         pw.print("    ");
14604                         long dur = ass.mTime;
14605                         if (ass.mNesting > 0) {
14606                             dur += now - ass.mStartTime;
14607                         }
14608                         TimeUtils.formatDuration(dur, pw);
14609                         pw.print(" (");
14610                         pw.print(ass.mCount);
14611                         pw.print(" times)");
14612                         pw.print("  ");
14613                         for (int i=0; i<ass.mStateTimes.length; i++) {
14614                             long amt = ass.mStateTimes[i];
14615                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14616                                 amt += now - ass.mLastStateUptime;
14617                             }
14618                             if (amt != 0) {
14619                                 pw.print(" ");
14620                                 pw.print(ProcessList.makeProcStateString(
14621                                             i + ActivityManager.MIN_PROCESS_STATE));
14622                                 pw.print("=");
14623                                 TimeUtils.formatDuration(amt, pw);
14624                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14625                                     pw.print("*");
14626                                 }
14627                             }
14628                         }
14629                         pw.println();
14630                         if (ass.mNesting > 0) {
14631                             pw.print("    Currently active: ");
14632                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14633                             pw.println();
14634                         }
14635                     }
14636                 }
14637             }
14638
14639         }
14640
14641         if (!printedAnything) {
14642             pw.println("  (nothing)");
14643         }
14644     }
14645
14646     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14647             String header, boolean needSep) {
14648         boolean printed = false;
14649         int whichAppId = -1;
14650         if (dumpPackage != null) {
14651             try {
14652                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14653                         dumpPackage, 0);
14654                 whichAppId = UserHandle.getAppId(info.uid);
14655             } catch (NameNotFoundException e) {
14656                 e.printStackTrace();
14657             }
14658         }
14659         for (int i=0; i<uids.size(); i++) {
14660             UidRecord uidRec = uids.valueAt(i);
14661             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14662                 continue;
14663             }
14664             if (!printed) {
14665                 printed = true;
14666                 if (needSep) {
14667                     pw.println();
14668                 }
14669                 pw.print("  ");
14670                 pw.println(header);
14671                 needSep = true;
14672             }
14673             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14674             pw.print(": "); pw.println(uidRec);
14675         }
14676         return printed;
14677     }
14678
14679     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14680             int opti, boolean dumpAll, String dumpPackage) {
14681         boolean needSep = false;
14682         boolean printedAnything = false;
14683         int numPers = 0;
14684
14685         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14686
14687         if (dumpAll) {
14688             final int NP = mProcessNames.getMap().size();
14689             for (int ip=0; ip<NP; ip++) {
14690                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14691                 final int NA = procs.size();
14692                 for (int ia=0; ia<NA; ia++) {
14693                     ProcessRecord r = procs.valueAt(ia);
14694                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14695                         continue;
14696                     }
14697                     if (!needSep) {
14698                         pw.println("  All known processes:");
14699                         needSep = true;
14700                         printedAnything = true;
14701                     }
14702                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14703                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14704                         pw.print(" "); pw.println(r);
14705                     r.dump(pw, "    ");
14706                     if (r.persistent) {
14707                         numPers++;
14708                     }
14709                 }
14710             }
14711         }
14712
14713         if (mIsolatedProcesses.size() > 0) {
14714             boolean printed = false;
14715             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14716                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14717                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14718                     continue;
14719                 }
14720                 if (!printed) {
14721                     if (needSep) {
14722                         pw.println();
14723                     }
14724                     pw.println("  Isolated process list (sorted by uid):");
14725                     printedAnything = true;
14726                     printed = true;
14727                     needSep = true;
14728                 }
14729                 pw.println(String.format("%sIsolated #%2d: %s",
14730                         "    ", i, r.toString()));
14731             }
14732         }
14733
14734         if (mActiveUids.size() > 0) {
14735             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14736                 printedAnything = needSep = true;
14737             }
14738         }
14739         if (mValidateUids.size() > 0) {
14740             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14741                 printedAnything = needSep = true;
14742             }
14743         }
14744
14745         if (mLruProcesses.size() > 0) {
14746             if (needSep) {
14747                 pw.println();
14748             }
14749             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14750                     pw.print(" total, non-act at ");
14751                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14752                     pw.print(", non-svc at ");
14753                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14754                     pw.println("):");
14755             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14756             needSep = true;
14757             printedAnything = true;
14758         }
14759
14760         if (dumpAll || dumpPackage != null) {
14761             synchronized (mPidsSelfLocked) {
14762                 boolean printed = false;
14763                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14764                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14765                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14766                         continue;
14767                     }
14768                     if (!printed) {
14769                         if (needSep) pw.println();
14770                         needSep = true;
14771                         pw.println("  PID mappings:");
14772                         printed = true;
14773                         printedAnything = true;
14774                     }
14775                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14776                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14777                 }
14778             }
14779         }
14780
14781         if (mForegroundProcesses.size() > 0) {
14782             synchronized (mPidsSelfLocked) {
14783                 boolean printed = false;
14784                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14785                     ProcessRecord r = mPidsSelfLocked.get(
14786                             mForegroundProcesses.valueAt(i).pid);
14787                     if (dumpPackage != null && (r == null
14788                             || !r.pkgList.containsKey(dumpPackage))) {
14789                         continue;
14790                     }
14791                     if (!printed) {
14792                         if (needSep) pw.println();
14793                         needSep = true;
14794                         pw.println("  Foreground Processes:");
14795                         printed = true;
14796                         printedAnything = true;
14797                     }
14798                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14799                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14800                 }
14801             }
14802         }
14803
14804         if (mPersistentStartingProcesses.size() > 0) {
14805             if (needSep) pw.println();
14806             needSep = true;
14807             printedAnything = true;
14808             pw.println("  Persisent processes that are starting:");
14809             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14810                     "Starting Norm", "Restarting PERS", dumpPackage);
14811         }
14812
14813         if (mRemovedProcesses.size() > 0) {
14814             if (needSep) pw.println();
14815             needSep = true;
14816             printedAnything = true;
14817             pw.println("  Processes that are being removed:");
14818             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14819                     "Removed Norm", "Removed PERS", dumpPackage);
14820         }
14821
14822         if (mProcessesOnHold.size() > 0) {
14823             if (needSep) pw.println();
14824             needSep = true;
14825             printedAnything = true;
14826             pw.println("  Processes that are on old until the system is ready:");
14827             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14828                     "OnHold Norm", "OnHold PERS", dumpPackage);
14829         }
14830
14831         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14832
14833         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14834         if (needSep) {
14835             printedAnything = true;
14836         }
14837
14838         if (dumpPackage == null) {
14839             pw.println();
14840             needSep = false;
14841             mUserController.dump(pw, dumpAll);
14842         }
14843         if (mHomeProcess != null && (dumpPackage == null
14844                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14845             if (needSep) {
14846                 pw.println();
14847                 needSep = false;
14848             }
14849             pw.println("  mHomeProcess: " + mHomeProcess);
14850         }
14851         if (mPreviousProcess != null && (dumpPackage == null
14852                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14853             if (needSep) {
14854                 pw.println();
14855                 needSep = false;
14856             }
14857             pw.println("  mPreviousProcess: " + mPreviousProcess);
14858         }
14859         if (dumpAll) {
14860             StringBuilder sb = new StringBuilder(128);
14861             sb.append("  mPreviousProcessVisibleTime: ");
14862             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14863             pw.println(sb);
14864         }
14865         if (mHeavyWeightProcess != null && (dumpPackage == null
14866                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14867             if (needSep) {
14868                 pw.println();
14869                 needSep = false;
14870             }
14871             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14872         }
14873         if (dumpPackage == null) {
14874             pw.println("  mConfiguration: " + mConfiguration);
14875         }
14876         if (dumpAll) {
14877             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14878             if (mCompatModePackages.getPackages().size() > 0) {
14879                 boolean printed = false;
14880                 for (Map.Entry<String, Integer> entry
14881                         : mCompatModePackages.getPackages().entrySet()) {
14882                     String pkg = entry.getKey();
14883                     int mode = entry.getValue();
14884                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14885                         continue;
14886                     }
14887                     if (!printed) {
14888                         pw.println("  mScreenCompatPackages:");
14889                         printed = true;
14890                     }
14891                     pw.print("    "); pw.print(pkg); pw.print(": ");
14892                             pw.print(mode); pw.println();
14893                 }
14894             }
14895         }
14896         if (dumpPackage == null) {
14897             pw.println("  mWakefulness="
14898                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14899             pw.println("  mSleepTokens=" + mSleepTokens);
14900             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14901                     + lockScreenShownToString());
14902             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14903             if (mRunningVoice != null) {
14904                 pw.println("  mRunningVoice=" + mRunningVoice);
14905                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14906             }
14907         }
14908         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14909                 || mOrigWaitForDebugger) {
14910             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14911                     || dumpPackage.equals(mOrigDebugApp)) {
14912                 if (needSep) {
14913                     pw.println();
14914                     needSep = false;
14915                 }
14916                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14917                         + " mDebugTransient=" + mDebugTransient
14918                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14919             }
14920         }
14921         if (mCurAppTimeTracker != null) {
14922             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14923         }
14924         if (mMemWatchProcesses.getMap().size() > 0) {
14925             pw.println("  Mem watch processes:");
14926             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14927                     = mMemWatchProcesses.getMap();
14928             for (int i=0; i<procs.size(); i++) {
14929                 final String proc = procs.keyAt(i);
14930                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14931                 for (int j=0; j<uids.size(); j++) {
14932                     if (needSep) {
14933                         pw.println();
14934                         needSep = false;
14935                     }
14936                     StringBuilder sb = new StringBuilder();
14937                     sb.append("    ").append(proc).append('/');
14938                     UserHandle.formatUid(sb, uids.keyAt(j));
14939                     Pair<Long, String> val = uids.valueAt(j);
14940                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14941                     if (val.second != null) {
14942                         sb.append(", report to ").append(val.second);
14943                     }
14944                     pw.println(sb.toString());
14945                 }
14946             }
14947             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14948             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14949             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14950                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14951         }
14952         if (mTrackAllocationApp != null) {
14953             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14954                 if (needSep) {
14955                     pw.println();
14956                     needSep = false;
14957                 }
14958                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14959             }
14960         }
14961         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14962                 || mProfileFd != null) {
14963             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14964                 if (needSep) {
14965                     pw.println();
14966                     needSep = false;
14967                 }
14968                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14969                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14970                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14971                         + mAutoStopProfiler);
14972                 pw.println("  mProfileType=" + mProfileType);
14973             }
14974         }
14975         if (mNativeDebuggingApp != null) {
14976             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14977                 if (needSep) {
14978                     pw.println();
14979                     needSep = false;
14980                 }
14981                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14982             }
14983         }
14984         if (dumpPackage == null) {
14985             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14986                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14987                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14988             }
14989             if (mController != null) {
14990                 pw.println("  mController=" + mController
14991                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14992             }
14993             if (dumpAll) {
14994                 pw.println("  Total persistent processes: " + numPers);
14995                 pw.println("  mProcessesReady=" + mProcessesReady
14996                         + " mSystemReady=" + mSystemReady
14997                         + " mBooted=" + mBooted
14998                         + " mFactoryTest=" + mFactoryTest);
14999                 pw.println("  mBooting=" + mBooting
15000                         + " mCallFinishBooting=" + mCallFinishBooting
15001                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15002                 pw.print("  mLastPowerCheckRealtime=");
15003                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15004                         pw.println("");
15005                 pw.print("  mLastPowerCheckUptime=");
15006                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15007                         pw.println("");
15008                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15009                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15010                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15011                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15012                         + " (" + mLruProcesses.size() + " total)"
15013                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15014                         + " mNumServiceProcs=" + mNumServiceProcs
15015                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15016                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15017                         + " mLastMemoryLevel=" + mLastMemoryLevel
15018                         + " mLastNumProcesses=" + mLastNumProcesses);
15019                 long now = SystemClock.uptimeMillis();
15020                 pw.print("  mLastIdleTime=");
15021                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15022                         pw.print(" mLowRamSinceLastIdle=");
15023                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15024                         pw.println();
15025             }
15026         }
15027
15028         if (!printedAnything) {
15029             pw.println("  (nothing)");
15030         }
15031     }
15032
15033     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15034             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15035         if (mProcessesToGc.size() > 0) {
15036             boolean printed = false;
15037             long now = SystemClock.uptimeMillis();
15038             for (int i=0; i<mProcessesToGc.size(); i++) {
15039                 ProcessRecord proc = mProcessesToGc.get(i);
15040                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15041                     continue;
15042                 }
15043                 if (!printed) {
15044                     if (needSep) pw.println();
15045                     needSep = true;
15046                     pw.println("  Processes that are waiting to GC:");
15047                     printed = true;
15048                 }
15049                 pw.print("    Process "); pw.println(proc);
15050                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15051                         pw.print(", last gced=");
15052                         pw.print(now-proc.lastRequestedGc);
15053                         pw.print(" ms ago, last lowMem=");
15054                         pw.print(now-proc.lastLowMemory);
15055                         pw.println(" ms ago");
15056
15057             }
15058         }
15059         return needSep;
15060     }
15061
15062     void printOomLevel(PrintWriter pw, String name, int adj) {
15063         pw.print("    ");
15064         if (adj >= 0) {
15065             pw.print(' ');
15066             if (adj < 10) pw.print(' ');
15067         } else {
15068             if (adj > -10) pw.print(' ');
15069         }
15070         pw.print(adj);
15071         pw.print(": ");
15072         pw.print(name);
15073         pw.print(" (");
15074         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15075         pw.println(")");
15076     }
15077
15078     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15079             int opti, boolean dumpAll) {
15080         boolean needSep = false;
15081
15082         if (mLruProcesses.size() > 0) {
15083             if (needSep) pw.println();
15084             needSep = true;
15085             pw.println("  OOM levels:");
15086             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15087             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15088             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15089             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15090             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15091             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15092             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15093             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15094             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15095             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15096             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15097             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15098             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15099             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15100
15101             if (needSep) pw.println();
15102             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15103                     pw.print(" total, non-act at ");
15104                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15105                     pw.print(", non-svc at ");
15106                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15107                     pw.println("):");
15108             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15109             needSep = true;
15110         }
15111
15112         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15113
15114         pw.println();
15115         pw.println("  mHomeProcess: " + mHomeProcess);
15116         pw.println("  mPreviousProcess: " + mPreviousProcess);
15117         if (mHeavyWeightProcess != null) {
15118             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15119         }
15120
15121         return true;
15122     }
15123
15124     /**
15125      * There are three ways to call this:
15126      *  - no provider specified: dump all the providers
15127      *  - a flattened component name that matched an existing provider was specified as the
15128      *    first arg: dump that one provider
15129      *  - the first arg isn't the flattened component name of an existing provider:
15130      *    dump all providers whose component contains the first arg as a substring
15131      */
15132     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15133             int opti, boolean dumpAll) {
15134         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15135     }
15136
15137     static class ItemMatcher {
15138         ArrayList<ComponentName> components;
15139         ArrayList<String> strings;
15140         ArrayList<Integer> objects;
15141         boolean all;
15142
15143         ItemMatcher() {
15144             all = true;
15145         }
15146
15147         void build(String name) {
15148             ComponentName componentName = ComponentName.unflattenFromString(name);
15149             if (componentName != null) {
15150                 if (components == null) {
15151                     components = new ArrayList<ComponentName>();
15152                 }
15153                 components.add(componentName);
15154                 all = false;
15155             } else {
15156                 int objectId = 0;
15157                 // Not a '/' separated full component name; maybe an object ID?
15158                 try {
15159                     objectId = Integer.parseInt(name, 16);
15160                     if (objects == null) {
15161                         objects = new ArrayList<Integer>();
15162                     }
15163                     objects.add(objectId);
15164                     all = false;
15165                 } catch (RuntimeException e) {
15166                     // Not an integer; just do string match.
15167                     if (strings == null) {
15168                         strings = new ArrayList<String>();
15169                     }
15170                     strings.add(name);
15171                     all = false;
15172                 }
15173             }
15174         }
15175
15176         int build(String[] args, int opti) {
15177             for (; opti<args.length; opti++) {
15178                 String name = args[opti];
15179                 if ("--".equals(name)) {
15180                     return opti+1;
15181                 }
15182                 build(name);
15183             }
15184             return opti;
15185         }
15186
15187         boolean match(Object object, ComponentName comp) {
15188             if (all) {
15189                 return true;
15190             }
15191             if (components != null) {
15192                 for (int i=0; i<components.size(); i++) {
15193                     if (components.get(i).equals(comp)) {
15194                         return true;
15195                     }
15196                 }
15197             }
15198             if (objects != null) {
15199                 for (int i=0; i<objects.size(); i++) {
15200                     if (System.identityHashCode(object) == objects.get(i)) {
15201                         return true;
15202                     }
15203                 }
15204             }
15205             if (strings != null) {
15206                 String flat = comp.flattenToString();
15207                 for (int i=0; i<strings.size(); i++) {
15208                     if (flat.contains(strings.get(i))) {
15209                         return true;
15210                     }
15211                 }
15212             }
15213             return false;
15214         }
15215     }
15216
15217     /**
15218      * There are three things that cmd can be:
15219      *  - a flattened component name that matches an existing activity
15220      *  - the cmd arg isn't the flattened component name of an existing activity:
15221      *    dump all activity whose component contains the cmd as a substring
15222      *  - A hex number of the ActivityRecord object instance.
15223      */
15224     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15225             int opti, boolean dumpAll) {
15226         ArrayList<ActivityRecord> activities;
15227
15228         synchronized (this) {
15229             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15230         }
15231
15232         if (activities.size() <= 0) {
15233             return false;
15234         }
15235
15236         String[] newArgs = new String[args.length - opti];
15237         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15238
15239         TaskRecord lastTask = null;
15240         boolean needSep = false;
15241         for (int i=activities.size()-1; i>=0; i--) {
15242             ActivityRecord r = activities.get(i);
15243             if (needSep) {
15244                 pw.println();
15245             }
15246             needSep = true;
15247             synchronized (this) {
15248                 if (lastTask != r.task) {
15249                     lastTask = r.task;
15250                     pw.print("TASK "); pw.print(lastTask.affinity);
15251                             pw.print(" id="); pw.println(lastTask.taskId);
15252                     if (dumpAll) {
15253                         lastTask.dump(pw, "  ");
15254                     }
15255                 }
15256             }
15257             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15258         }
15259         return true;
15260     }
15261
15262     /**
15263      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15264      * there is a thread associated with the activity.
15265      */
15266     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15267             final ActivityRecord r, String[] args, boolean dumpAll) {
15268         String innerPrefix = prefix + "  ";
15269         synchronized (this) {
15270             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15271                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15272                     pw.print(" pid=");
15273                     if (r.app != null) pw.println(r.app.pid);
15274                     else pw.println("(not running)");
15275             if (dumpAll) {
15276                 r.dump(pw, innerPrefix);
15277             }
15278         }
15279         if (r.app != null && r.app.thread != null) {
15280             // flush anything that is already in the PrintWriter since the thread is going
15281             // to write to the file descriptor directly
15282             pw.flush();
15283             try {
15284                 TransferPipe tp = new TransferPipe();
15285                 try {
15286                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15287                             r.appToken, innerPrefix, args);
15288                     tp.go(fd);
15289                 } finally {
15290                     tp.kill();
15291                 }
15292             } catch (IOException e) {
15293                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15294             } catch (RemoteException e) {
15295                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15296             }
15297         }
15298     }
15299
15300     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15301             int opti, boolean dumpAll, String dumpPackage) {
15302         boolean needSep = false;
15303         boolean onlyHistory = false;
15304         boolean printedAnything = false;
15305
15306         if ("history".equals(dumpPackage)) {
15307             if (opti < args.length && "-s".equals(args[opti])) {
15308                 dumpAll = false;
15309             }
15310             onlyHistory = true;
15311             dumpPackage = null;
15312         }
15313
15314         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15315         if (!onlyHistory && dumpAll) {
15316             if (mRegisteredReceivers.size() > 0) {
15317                 boolean printed = false;
15318                 Iterator it = mRegisteredReceivers.values().iterator();
15319                 while (it.hasNext()) {
15320                     ReceiverList r = (ReceiverList)it.next();
15321                     if (dumpPackage != null && (r.app == null ||
15322                             !dumpPackage.equals(r.app.info.packageName))) {
15323                         continue;
15324                     }
15325                     if (!printed) {
15326                         pw.println("  Registered Receivers:");
15327                         needSep = true;
15328                         printed = true;
15329                         printedAnything = true;
15330                     }
15331                     pw.print("  * "); pw.println(r);
15332                     r.dump(pw, "    ");
15333                 }
15334             }
15335
15336             if (mReceiverResolver.dump(pw, needSep ?
15337                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15338                     "    ", dumpPackage, false, false)) {
15339                 needSep = true;
15340                 printedAnything = true;
15341             }
15342         }
15343
15344         for (BroadcastQueue q : mBroadcastQueues) {
15345             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15346             printedAnything |= needSep;
15347         }
15348
15349         needSep = true;
15350
15351         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15352             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15353                 if (needSep) {
15354                     pw.println();
15355                 }
15356                 needSep = true;
15357                 printedAnything = true;
15358                 pw.print("  Sticky broadcasts for user ");
15359                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15360                 StringBuilder sb = new StringBuilder(128);
15361                 for (Map.Entry<String, ArrayList<Intent>> ent
15362                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15363                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15364                     if (dumpAll) {
15365                         pw.println(":");
15366                         ArrayList<Intent> intents = ent.getValue();
15367                         final int N = intents.size();
15368                         for (int i=0; i<N; i++) {
15369                             sb.setLength(0);
15370                             sb.append("    Intent: ");
15371                             intents.get(i).toShortString(sb, false, true, false, false);
15372                             pw.println(sb.toString());
15373                             Bundle bundle = intents.get(i).getExtras();
15374                             if (bundle != null) {
15375                                 pw.print("      ");
15376                                 pw.println(bundle.toString());
15377                             }
15378                         }
15379                     } else {
15380                         pw.println("");
15381                     }
15382                 }
15383             }
15384         }
15385
15386         if (!onlyHistory && dumpAll) {
15387             pw.println();
15388             for (BroadcastQueue queue : mBroadcastQueues) {
15389                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15390                         + queue.mBroadcastsScheduled);
15391             }
15392             pw.println("  mHandler:");
15393             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15394             needSep = true;
15395             printedAnything = true;
15396         }
15397
15398         if (!printedAnything) {
15399             pw.println("  (nothing)");
15400         }
15401     }
15402
15403     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15404             int opti, boolean dumpAll, String dumpPackage) {
15405         if (mCurBroadcastStats == null) {
15406             return;
15407         }
15408
15409         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15410         final long now = SystemClock.elapsedRealtime();
15411         if (mLastBroadcastStats != null) {
15412             pw.print("  Last stats (from ");
15413             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15414             pw.print(" to ");
15415             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15416             pw.print(", ");
15417             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15418                     - mLastBroadcastStats.mStartUptime, pw);
15419             pw.println(" uptime):");
15420             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15421                 pw.println("    (nothing)");
15422             }
15423             pw.println();
15424         }
15425         pw.print("  Current stats (from ");
15426         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15427         pw.print(" to now, ");
15428         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15429                 - mCurBroadcastStats.mStartUptime, pw);
15430         pw.println(" uptime):");
15431         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15432             pw.println("    (nothing)");
15433         }
15434     }
15435
15436     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15437             int opti, boolean fullCheckin, String dumpPackage) {
15438         if (mCurBroadcastStats == null) {
15439             return;
15440         }
15441
15442         if (mLastBroadcastStats != null) {
15443             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15444             if (fullCheckin) {
15445                 mLastBroadcastStats = null;
15446                 return;
15447             }
15448         }
15449         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15450         if (fullCheckin) {
15451             mCurBroadcastStats = null;
15452         }
15453     }
15454
15455     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15456             int opti, boolean dumpAll, String dumpPackage) {
15457         boolean needSep;
15458         boolean printedAnything = false;
15459
15460         ItemMatcher matcher = new ItemMatcher();
15461         matcher.build(args, opti);
15462
15463         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15464
15465         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15466         printedAnything |= needSep;
15467
15468         if (mLaunchingProviders.size() > 0) {
15469             boolean printed = false;
15470             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15471                 ContentProviderRecord r = mLaunchingProviders.get(i);
15472                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15473                     continue;
15474                 }
15475                 if (!printed) {
15476                     if (needSep) pw.println();
15477                     needSep = true;
15478                     pw.println("  Launching content providers:");
15479                     printed = true;
15480                     printedAnything = true;
15481                 }
15482                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15483                         pw.println(r);
15484             }
15485         }
15486
15487         if (!printedAnything) {
15488             pw.println("  (nothing)");
15489         }
15490     }
15491
15492     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15493             int opti, boolean dumpAll, String dumpPackage) {
15494         boolean needSep = false;
15495         boolean printedAnything = false;
15496
15497         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15498
15499         if (mGrantedUriPermissions.size() > 0) {
15500             boolean printed = false;
15501             int dumpUid = -2;
15502             if (dumpPackage != null) {
15503                 try {
15504                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15505                             MATCH_UNINSTALLED_PACKAGES, 0);
15506                 } catch (NameNotFoundException e) {
15507                     dumpUid = -1;
15508                 }
15509             }
15510             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15511                 int uid = mGrantedUriPermissions.keyAt(i);
15512                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15513                     continue;
15514                 }
15515                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15516                 if (!printed) {
15517                     if (needSep) pw.println();
15518                     needSep = true;
15519                     pw.println("  Granted Uri Permissions:");
15520                     printed = true;
15521                     printedAnything = true;
15522                 }
15523                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15524                 for (UriPermission perm : perms.values()) {
15525                     pw.print("    "); pw.println(perm);
15526                     if (dumpAll) {
15527                         perm.dump(pw, "      ");
15528                     }
15529                 }
15530             }
15531         }
15532
15533         if (!printedAnything) {
15534             pw.println("  (nothing)");
15535         }
15536     }
15537
15538     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15539             int opti, boolean dumpAll, String dumpPackage) {
15540         boolean printed = false;
15541
15542         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15543
15544         if (mIntentSenderRecords.size() > 0) {
15545             Iterator<WeakReference<PendingIntentRecord>> it
15546                     = mIntentSenderRecords.values().iterator();
15547             while (it.hasNext()) {
15548                 WeakReference<PendingIntentRecord> ref = it.next();
15549                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15550                 if (dumpPackage != null && (rec == null
15551                         || !dumpPackage.equals(rec.key.packageName))) {
15552                     continue;
15553                 }
15554                 printed = true;
15555                 if (rec != null) {
15556                     pw.print("  * "); pw.println(rec);
15557                     if (dumpAll) {
15558                         rec.dump(pw, "    ");
15559                     }
15560                 } else {
15561                     pw.print("  * "); pw.println(ref);
15562                 }
15563             }
15564         }
15565
15566         if (!printed) {
15567             pw.println("  (nothing)");
15568         }
15569     }
15570
15571     private static final int dumpProcessList(PrintWriter pw,
15572             ActivityManagerService service, List list,
15573             String prefix, String normalLabel, String persistentLabel,
15574             String dumpPackage) {
15575         int numPers = 0;
15576         final int N = list.size()-1;
15577         for (int i=N; i>=0; i--) {
15578             ProcessRecord r = (ProcessRecord)list.get(i);
15579             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15580                 continue;
15581             }
15582             pw.println(String.format("%s%s #%2d: %s",
15583                     prefix, (r.persistent ? persistentLabel : normalLabel),
15584                     i, r.toString()));
15585             if (r.persistent) {
15586                 numPers++;
15587             }
15588         }
15589         return numPers;
15590     }
15591
15592     private static final boolean dumpProcessOomList(PrintWriter pw,
15593             ActivityManagerService service, List<ProcessRecord> origList,
15594             String prefix, String normalLabel, String persistentLabel,
15595             boolean inclDetails, String dumpPackage) {
15596
15597         ArrayList<Pair<ProcessRecord, Integer>> list
15598                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15599         for (int i=0; i<origList.size(); i++) {
15600             ProcessRecord r = origList.get(i);
15601             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15602                 continue;
15603             }
15604             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15605         }
15606
15607         if (list.size() <= 0) {
15608             return false;
15609         }
15610
15611         Comparator<Pair<ProcessRecord, Integer>> comparator
15612                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15613             @Override
15614             public int compare(Pair<ProcessRecord, Integer> object1,
15615                     Pair<ProcessRecord, Integer> object2) {
15616                 if (object1.first.setAdj != object2.first.setAdj) {
15617                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15618                 }
15619                 if (object1.first.setProcState != object2.first.setProcState) {
15620                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15621                 }
15622                 if (object1.second.intValue() != object2.second.intValue()) {
15623                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15624                 }
15625                 return 0;
15626             }
15627         };
15628
15629         Collections.sort(list, comparator);
15630
15631         final long curRealtime = SystemClock.elapsedRealtime();
15632         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15633         final long curUptime = SystemClock.uptimeMillis();
15634         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15635
15636         for (int i=list.size()-1; i>=0; i--) {
15637             ProcessRecord r = list.get(i).first;
15638             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15639             char schedGroup;
15640             switch (r.setSchedGroup) {
15641                 case ProcessList.SCHED_GROUP_BACKGROUND:
15642                     schedGroup = 'B';
15643                     break;
15644                 case ProcessList.SCHED_GROUP_DEFAULT:
15645                     schedGroup = 'F';
15646                     break;
15647                 case ProcessList.SCHED_GROUP_TOP_APP:
15648                     schedGroup = 'T';
15649                     break;
15650                 default:
15651                     schedGroup = '?';
15652                     break;
15653             }
15654             char foreground;
15655             if (r.foregroundActivities) {
15656                 foreground = 'A';
15657             } else if (r.foregroundServices) {
15658                 foreground = 'S';
15659             } else {
15660                 foreground = ' ';
15661             }
15662             String procState = ProcessList.makeProcStateString(r.curProcState);
15663             pw.print(prefix);
15664             pw.print(r.persistent ? persistentLabel : normalLabel);
15665             pw.print(" #");
15666             int num = (origList.size()-1)-list.get(i).second;
15667             if (num < 10) pw.print(' ');
15668             pw.print(num);
15669             pw.print(": ");
15670             pw.print(oomAdj);
15671             pw.print(' ');
15672             pw.print(schedGroup);
15673             pw.print('/');
15674             pw.print(foreground);
15675             pw.print('/');
15676             pw.print(procState);
15677             pw.print(" trm:");
15678             if (r.trimMemoryLevel < 10) pw.print(' ');
15679             pw.print(r.trimMemoryLevel);
15680             pw.print(' ');
15681             pw.print(r.toShortString());
15682             pw.print(" (");
15683             pw.print(r.adjType);
15684             pw.println(')');
15685             if (r.adjSource != null || r.adjTarget != null) {
15686                 pw.print(prefix);
15687                 pw.print("    ");
15688                 if (r.adjTarget instanceof ComponentName) {
15689                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15690                 } else if (r.adjTarget != null) {
15691                     pw.print(r.adjTarget.toString());
15692                 } else {
15693                     pw.print("{null}");
15694                 }
15695                 pw.print("<=");
15696                 if (r.adjSource instanceof ProcessRecord) {
15697                     pw.print("Proc{");
15698                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15699                     pw.println("}");
15700                 } else if (r.adjSource != null) {
15701                     pw.println(r.adjSource.toString());
15702                 } else {
15703                     pw.println("{null}");
15704                 }
15705             }
15706             if (inclDetails) {
15707                 pw.print(prefix);
15708                 pw.print("    ");
15709                 pw.print("oom: max="); pw.print(r.maxAdj);
15710                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15711                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15712                 pw.print(" cur="); pw.print(r.curAdj);
15713                 pw.print(" set="); pw.println(r.setAdj);
15714                 pw.print(prefix);
15715                 pw.print("    ");
15716                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15717                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15718                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15719                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15720                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15721                 pw.println();
15722                 pw.print(prefix);
15723                 pw.print("    ");
15724                 pw.print("cached="); pw.print(r.cached);
15725                 pw.print(" empty="); pw.print(r.empty);
15726                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15727
15728                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15729                     if (r.lastWakeTime != 0) {
15730                         long wtime;
15731                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15732                         synchronized (stats) {
15733                             wtime = stats.getProcessWakeTime(r.info.uid,
15734                                     r.pid, curRealtime);
15735                         }
15736                         long timeUsed = wtime - r.lastWakeTime;
15737                         pw.print(prefix);
15738                         pw.print("    ");
15739                         pw.print("keep awake over ");
15740                         TimeUtils.formatDuration(realtimeSince, pw);
15741                         pw.print(" used ");
15742                         TimeUtils.formatDuration(timeUsed, pw);
15743                         pw.print(" (");
15744                         pw.print((timeUsed*100)/realtimeSince);
15745                         pw.println("%)");
15746                     }
15747                     if (r.lastCpuTime != 0) {
15748                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15749                         pw.print(prefix);
15750                         pw.print("    ");
15751                         pw.print("run cpu over ");
15752                         TimeUtils.formatDuration(uptimeSince, pw);
15753                         pw.print(" used ");
15754                         TimeUtils.formatDuration(timeUsed, pw);
15755                         pw.print(" (");
15756                         pw.print((timeUsed*100)/uptimeSince);
15757                         pw.println("%)");
15758                     }
15759                 }
15760             }
15761         }
15762         return true;
15763     }
15764
15765     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15766             String[] args) {
15767         ArrayList<ProcessRecord> procs;
15768         synchronized (this) {
15769             if (args != null && args.length > start
15770                     && args[start].charAt(0) != '-') {
15771                 procs = new ArrayList<ProcessRecord>();
15772                 int pid = -1;
15773                 try {
15774                     pid = Integer.parseInt(args[start]);
15775                 } catch (NumberFormatException e) {
15776                 }
15777                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15778                     ProcessRecord proc = mLruProcesses.get(i);
15779                     if (proc.pid == pid) {
15780                         procs.add(proc);
15781                     } else if (allPkgs && proc.pkgList != null
15782                             && proc.pkgList.containsKey(args[start])) {
15783                         procs.add(proc);
15784                     } else if (proc.processName.equals(args[start])) {
15785                         procs.add(proc);
15786                     }
15787                 }
15788                 if (procs.size() <= 0) {
15789                     return null;
15790                 }
15791             } else {
15792                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15793             }
15794         }
15795         return procs;
15796     }
15797
15798     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15799             PrintWriter pw, String[] args) {
15800         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15801         if (procs == null) {
15802             pw.println("No process found for: " + args[0]);
15803             return;
15804         }
15805
15806         long uptime = SystemClock.uptimeMillis();
15807         long realtime = SystemClock.elapsedRealtime();
15808         pw.println("Applications Graphics Acceleration Info:");
15809         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15810
15811         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15812             ProcessRecord r = procs.get(i);
15813             if (r.thread != null) {
15814                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15815                 pw.flush();
15816                 try {
15817                     TransferPipe tp = new TransferPipe();
15818                     try {
15819                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15820                         tp.go(fd);
15821                     } finally {
15822                         tp.kill();
15823                     }
15824                 } catch (IOException e) {
15825                     pw.println("Failure while dumping the app: " + r);
15826                     pw.flush();
15827                 } catch (RemoteException e) {
15828                     pw.println("Got a RemoteException while dumping the app " + r);
15829                     pw.flush();
15830                 }
15831             }
15832         }
15833     }
15834
15835     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15836         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15837         if (procs == null) {
15838             pw.println("No process found for: " + args[0]);
15839             return;
15840         }
15841
15842         pw.println("Applications Database Info:");
15843
15844         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15845             ProcessRecord r = procs.get(i);
15846             if (r.thread != null) {
15847                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15848                 pw.flush();
15849                 try {
15850                     TransferPipe tp = new TransferPipe();
15851                     try {
15852                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15853                         tp.go(fd);
15854                     } finally {
15855                         tp.kill();
15856                     }
15857                 } catch (IOException e) {
15858                     pw.println("Failure while dumping the app: " + r);
15859                     pw.flush();
15860                 } catch (RemoteException e) {
15861                     pw.println("Got a RemoteException while dumping the app " + r);
15862                     pw.flush();
15863                 }
15864             }
15865         }
15866     }
15867
15868     final static class MemItem {
15869         final boolean isProc;
15870         final String label;
15871         final String shortLabel;
15872         final long pss;
15873         final long swapPss;
15874         final int id;
15875         final boolean hasActivities;
15876         ArrayList<MemItem> subitems;
15877
15878         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15879                 boolean _hasActivities) {
15880             isProc = true;
15881             label = _label;
15882             shortLabel = _shortLabel;
15883             pss = _pss;
15884             swapPss = _swapPss;
15885             id = _id;
15886             hasActivities = _hasActivities;
15887         }
15888
15889         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15890             isProc = false;
15891             label = _label;
15892             shortLabel = _shortLabel;
15893             pss = _pss;
15894             swapPss = _swapPss;
15895             id = _id;
15896             hasActivities = false;
15897         }
15898     }
15899
15900     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15901             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15902         if (sort && !isCompact) {
15903             Collections.sort(items, new Comparator<MemItem>() {
15904                 @Override
15905                 public int compare(MemItem lhs, MemItem rhs) {
15906                     if (lhs.pss < rhs.pss) {
15907                         return 1;
15908                     } else if (lhs.pss > rhs.pss) {
15909                         return -1;
15910                     }
15911                     return 0;
15912                 }
15913             });
15914         }
15915
15916         for (int i=0; i<items.size(); i++) {
15917             MemItem mi = items.get(i);
15918             if (!isCompact) {
15919                 if (dumpSwapPss) {
15920                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15921                             mi.label, stringifyKBSize(mi.swapPss));
15922                 } else {
15923                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15924                 }
15925             } else if (mi.isProc) {
15926                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15927                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15928                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15929                 pw.println(mi.hasActivities ? ",a" : ",e");
15930             } else {
15931                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15932                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15933             }
15934             if (mi.subitems != null) {
15935                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15936                         true, isCompact, dumpSwapPss);
15937             }
15938         }
15939     }
15940
15941     // These are in KB.
15942     static final long[] DUMP_MEM_BUCKETS = new long[] {
15943         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15944         120*1024, 160*1024, 200*1024,
15945         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15946         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15947     };
15948
15949     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15950             boolean stackLike) {
15951         int start = label.lastIndexOf('.');
15952         if (start >= 0) start++;
15953         else start = 0;
15954         int end = label.length();
15955         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15956             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15957                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15958                 out.append(bucket);
15959                 out.append(stackLike ? "MB." : "MB ");
15960                 out.append(label, start, end);
15961                 return;
15962             }
15963         }
15964         out.append(memKB/1024);
15965         out.append(stackLike ? "MB." : "MB ");
15966         out.append(label, start, end);
15967     }
15968
15969     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15970             ProcessList.NATIVE_ADJ,
15971             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15972             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15973             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15974             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15975             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15976             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15977     };
15978     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15979             "Native",
15980             "System", "Persistent", "Persistent Service", "Foreground",
15981             "Visible", "Perceptible",
15982             "Heavy Weight", "Backup",
15983             "A Services", "Home",
15984             "Previous", "B Services", "Cached"
15985     };
15986     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15987             "native",
15988             "sys", "pers", "persvc", "fore",
15989             "vis", "percept",
15990             "heavy", "backup",
15991             "servicea", "home",
15992             "prev", "serviceb", "cached"
15993     };
15994
15995     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15996             long realtime, boolean isCheckinRequest, boolean isCompact) {
15997         if (isCompact) {
15998             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15999         }
16000         if (isCheckinRequest || isCompact) {
16001             // short checkin version
16002             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16003         } else {
16004             pw.println("Applications Memory Usage (in Kilobytes):");
16005             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16006         }
16007     }
16008
16009     private static final int KSM_SHARED = 0;
16010     private static final int KSM_SHARING = 1;
16011     private static final int KSM_UNSHARED = 2;
16012     private static final int KSM_VOLATILE = 3;
16013
16014     private final long[] getKsmInfo() {
16015         long[] longOut = new long[4];
16016         final int[] SINGLE_LONG_FORMAT = new int[] {
16017             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16018         };
16019         long[] longTmp = new long[1];
16020         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16021                 SINGLE_LONG_FORMAT, null, longTmp, null);
16022         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16023         longTmp[0] = 0;
16024         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16025                 SINGLE_LONG_FORMAT, null, longTmp, null);
16026         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16027         longTmp[0] = 0;
16028         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16029                 SINGLE_LONG_FORMAT, null, longTmp, null);
16030         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16031         longTmp[0] = 0;
16032         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16033                 SINGLE_LONG_FORMAT, null, longTmp, null);
16034         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16035         return longOut;
16036     }
16037
16038     private static String stringifySize(long size, int order) {
16039         Locale locale = Locale.US;
16040         switch (order) {
16041             case 1:
16042                 return String.format(locale, "%,13d", size);
16043             case 1024:
16044                 return String.format(locale, "%,9dK", size / 1024);
16045             case 1024 * 1024:
16046                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16047             case 1024 * 1024 * 1024:
16048                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16049             default:
16050                 throw new IllegalArgumentException("Invalid size order");
16051         }
16052     }
16053
16054     private static String stringifyKBSize(long size) {
16055         return stringifySize(size * 1024, 1024);
16056     }
16057
16058     // Update this version number in case you change the 'compact' format
16059     private static final int MEMINFO_COMPACT_VERSION = 1;
16060
16061     final void dumpApplicationMemoryUsage(FileDescriptor fd,
16062             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16063         boolean dumpDetails = false;
16064         boolean dumpFullDetails = false;
16065         boolean dumpDalvik = false;
16066         boolean dumpSummaryOnly = false;
16067         boolean dumpUnreachable = false;
16068         boolean oomOnly = false;
16069         boolean isCompact = false;
16070         boolean localOnly = false;
16071         boolean packages = false;
16072         boolean isCheckinRequest = false;
16073         boolean dumpSwapPss = false;
16074
16075         int opti = 0;
16076         while (opti < args.length) {
16077             String opt = args[opti];
16078             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16079                 break;
16080             }
16081             opti++;
16082             if ("-a".equals(opt)) {
16083                 dumpDetails = true;
16084                 dumpFullDetails = true;
16085                 dumpDalvik = true;
16086                 dumpSwapPss = true;
16087             } else if ("-d".equals(opt)) {
16088                 dumpDalvik = true;
16089             } else if ("-c".equals(opt)) {
16090                 isCompact = true;
16091             } else if ("-s".equals(opt)) {
16092                 dumpDetails = true;
16093                 dumpSummaryOnly = true;
16094             } else if ("-S".equals(opt)) {
16095                 dumpSwapPss = true;
16096             } else if ("--unreachable".equals(opt)) {
16097                 dumpUnreachable = true;
16098             } else if ("--oom".equals(opt)) {
16099                 oomOnly = true;
16100             } else if ("--local".equals(opt)) {
16101                 localOnly = true;
16102             } else if ("--package".equals(opt)) {
16103                 packages = true;
16104             } else if ("--checkin".equals(opt)) {
16105                 isCheckinRequest = true;
16106
16107             } else if ("-h".equals(opt)) {
16108                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16109                 pw.println("  -a: include all available information for each process.");
16110                 pw.println("  -d: include dalvik details.");
16111                 pw.println("  -c: dump in a compact machine-parseable representation.");
16112                 pw.println("  -s: dump only summary of application memory usage.");
16113                 pw.println("  -S: dump also SwapPss.");
16114                 pw.println("  --oom: only show processes organized by oom adj.");
16115                 pw.println("  --local: only collect details locally, don't call process.");
16116                 pw.println("  --package: interpret process arg as package, dumping all");
16117                 pw.println("             processes that have loaded that package.");
16118                 pw.println("  --checkin: dump data for a checkin");
16119                 pw.println("If [process] is specified it can be the name or ");
16120                 pw.println("pid of a specific process to dump.");
16121                 return;
16122             } else {
16123                 pw.println("Unknown argument: " + opt + "; use -h for help");
16124             }
16125         }
16126
16127         long uptime = SystemClock.uptimeMillis();
16128         long realtime = SystemClock.elapsedRealtime();
16129         final long[] tmpLong = new long[1];
16130
16131         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16132         if (procs == null) {
16133             // No Java processes.  Maybe they want to print a native process.
16134             if (args != null && args.length > opti
16135                     && args[opti].charAt(0) != '-') {
16136                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16137                         = new ArrayList<ProcessCpuTracker.Stats>();
16138                 updateCpuStatsNow();
16139                 int findPid = -1;
16140                 try {
16141                     findPid = Integer.parseInt(args[opti]);
16142                 } catch (NumberFormatException e) {
16143                 }
16144                 synchronized (mProcessCpuTracker) {
16145                     final int N = mProcessCpuTracker.countStats();
16146                     for (int i=0; i<N; i++) {
16147                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16148                         if (st.pid == findPid || (st.baseName != null
16149                                 && st.baseName.equals(args[opti]))) {
16150                             nativeProcs.add(st);
16151                         }
16152                     }
16153                 }
16154                 if (nativeProcs.size() > 0) {
16155                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16156                             isCompact);
16157                     Debug.MemoryInfo mi = null;
16158                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16159                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16160                         final int pid = r.pid;
16161                         if (!isCheckinRequest && dumpDetails) {
16162                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16163                         }
16164                         if (mi == null) {
16165                             mi = new Debug.MemoryInfo();
16166                         }
16167                         if (dumpDetails || (!brief && !oomOnly)) {
16168                             Debug.getMemoryInfo(pid, mi);
16169                         } else {
16170                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16171                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16172                         }
16173                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16174                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16175                         if (isCheckinRequest) {
16176                             pw.println();
16177                         }
16178                     }
16179                     return;
16180                 }
16181             }
16182             pw.println("No process found for: " + args[opti]);
16183             return;
16184         }
16185
16186         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16187             dumpDetails = true;
16188         }
16189
16190         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16191
16192         String[] innerArgs = new String[args.length-opti];
16193         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16194
16195         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16196         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16197         long nativePss = 0;
16198         long nativeSwapPss = 0;
16199         long dalvikPss = 0;
16200         long dalvikSwapPss = 0;
16201         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16202                 EmptyArray.LONG;
16203         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16204                 EmptyArray.LONG;
16205         long otherPss = 0;
16206         long otherSwapPss = 0;
16207         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16208         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16209
16210         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16211         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16212         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16213                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16214
16215         long totalPss = 0;
16216         long totalSwapPss = 0;
16217         long cachedPss = 0;
16218         long cachedSwapPss = 0;
16219         boolean hasSwapPss = false;
16220
16221         Debug.MemoryInfo mi = null;
16222         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16223             final ProcessRecord r = procs.get(i);
16224             final IApplicationThread thread;
16225             final int pid;
16226             final int oomAdj;
16227             final boolean hasActivities;
16228             synchronized (this) {
16229                 thread = r.thread;
16230                 pid = r.pid;
16231                 oomAdj = r.getSetAdjWithServices();
16232                 hasActivities = r.activities.size() > 0;
16233             }
16234             if (thread != null) {
16235                 if (!isCheckinRequest && dumpDetails) {
16236                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16237                 }
16238                 if (mi == null) {
16239                     mi = new Debug.MemoryInfo();
16240                 }
16241                 if (dumpDetails || (!brief && !oomOnly)) {
16242                     Debug.getMemoryInfo(pid, mi);
16243                     hasSwapPss = mi.hasSwappedOutPss;
16244                 } else {
16245                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16246                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16247                 }
16248                 if (dumpDetails) {
16249                     if (localOnly) {
16250                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16251                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16252                         if (isCheckinRequest) {
16253                             pw.println();
16254                         }
16255                     } else {
16256                         try {
16257                             pw.flush();
16258                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16259                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16260                         } catch (RemoteException e) {
16261                             if (!isCheckinRequest) {
16262                                 pw.println("Got RemoteException!");
16263                                 pw.flush();
16264                             }
16265                         }
16266                     }
16267                 }
16268
16269                 final long myTotalPss = mi.getTotalPss();
16270                 final long myTotalUss = mi.getTotalUss();
16271                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16272
16273                 synchronized (this) {
16274                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16275                         // Record this for posterity if the process has been stable.
16276                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16277                     }
16278                 }
16279
16280                 if (!isCheckinRequest && mi != null) {
16281                     totalPss += myTotalPss;
16282                     totalSwapPss += myTotalSwapPss;
16283                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16284                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16285                             myTotalSwapPss, pid, hasActivities);
16286                     procMems.add(pssItem);
16287                     procMemsMap.put(pid, pssItem);
16288
16289                     nativePss += mi.nativePss;
16290                     nativeSwapPss += mi.nativeSwappedOutPss;
16291                     dalvikPss += mi.dalvikPss;
16292                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16293                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16294                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16295                         dalvikSubitemSwapPss[j] +=
16296                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16297                     }
16298                     otherPss += mi.otherPss;
16299                     otherSwapPss += mi.otherSwappedOutPss;
16300                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16301                         long mem = mi.getOtherPss(j);
16302                         miscPss[j] += mem;
16303                         otherPss -= mem;
16304                         mem = mi.getOtherSwappedOutPss(j);
16305                         miscSwapPss[j] += mem;
16306                         otherSwapPss -= mem;
16307                     }
16308
16309                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16310                         cachedPss += myTotalPss;
16311                         cachedSwapPss += myTotalSwapPss;
16312                     }
16313
16314                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16315                         if (oomIndex == (oomPss.length - 1)
16316                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16317                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16318                             oomPss[oomIndex] += myTotalPss;
16319                             oomSwapPss[oomIndex] += myTotalSwapPss;
16320                             if (oomProcs[oomIndex] == null) {
16321                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16322                             }
16323                             oomProcs[oomIndex].add(pssItem);
16324                             break;
16325                         }
16326                     }
16327                 }
16328             }
16329         }
16330
16331         long nativeProcTotalPss = 0;
16332
16333         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16334             // If we are showing aggregations, also look for native processes to
16335             // include so that our aggregations are more accurate.
16336             updateCpuStatsNow();
16337             mi = null;
16338             synchronized (mProcessCpuTracker) {
16339                 final int N = mProcessCpuTracker.countStats();
16340                 for (int i=0; i<N; i++) {
16341                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16342                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16343                         if (mi == null) {
16344                             mi = new Debug.MemoryInfo();
16345                         }
16346                         if (!brief && !oomOnly) {
16347                             Debug.getMemoryInfo(st.pid, mi);
16348                         } else {
16349                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16350                             mi.nativePrivateDirty = (int)tmpLong[0];
16351                         }
16352
16353                         final long myTotalPss = mi.getTotalPss();
16354                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16355                         totalPss += myTotalPss;
16356                         nativeProcTotalPss += myTotalPss;
16357
16358                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16359                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16360                         procMems.add(pssItem);
16361
16362                         nativePss += mi.nativePss;
16363                         nativeSwapPss += mi.nativeSwappedOutPss;
16364                         dalvikPss += mi.dalvikPss;
16365                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16366                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16367                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16368                             dalvikSubitemSwapPss[j] +=
16369                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16370                         }
16371                         otherPss += mi.otherPss;
16372                         otherSwapPss += mi.otherSwappedOutPss;
16373                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16374                             long mem = mi.getOtherPss(j);
16375                             miscPss[j] += mem;
16376                             otherPss -= mem;
16377                             mem = mi.getOtherSwappedOutPss(j);
16378                             miscSwapPss[j] += mem;
16379                             otherSwapPss -= mem;
16380                         }
16381                         oomPss[0] += myTotalPss;
16382                         oomSwapPss[0] += myTotalSwapPss;
16383                         if (oomProcs[0] == null) {
16384                             oomProcs[0] = new ArrayList<MemItem>();
16385                         }
16386                         oomProcs[0].add(pssItem);
16387                     }
16388                 }
16389             }
16390
16391             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16392
16393             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16394             final MemItem dalvikItem =
16395                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16396             if (dalvikSubitemPss.length > 0) {
16397                 dalvikItem.subitems = new ArrayList<MemItem>();
16398                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16399                     final String name = Debug.MemoryInfo.getOtherLabel(
16400                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16401                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16402                                     dalvikSubitemSwapPss[j], j));
16403                 }
16404             }
16405             catMems.add(dalvikItem);
16406             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16407             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16408                 String label = Debug.MemoryInfo.getOtherLabel(j);
16409                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16410             }
16411
16412             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16413             for (int j=0; j<oomPss.length; j++) {
16414                 if (oomPss[j] != 0) {
16415                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16416                             : DUMP_MEM_OOM_LABEL[j];
16417                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16418                             DUMP_MEM_OOM_ADJ[j]);
16419                     item.subitems = oomProcs[j];
16420                     oomMems.add(item);
16421                 }
16422             }
16423
16424             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16425             if (!brief && !oomOnly && !isCompact) {
16426                 pw.println();
16427                 pw.println("Total PSS by process:");
16428                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16429                 pw.println();
16430             }
16431             if (!isCompact) {
16432                 pw.println("Total PSS by OOM adjustment:");
16433             }
16434             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16435             if (!brief && !oomOnly) {
16436                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16437                 if (!isCompact) {
16438                     out.println();
16439                     out.println("Total PSS by category:");
16440                 }
16441                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16442             }
16443             if (!isCompact) {
16444                 pw.println();
16445             }
16446             MemInfoReader memInfo = new MemInfoReader();
16447             memInfo.readMemInfo();
16448             if (nativeProcTotalPss > 0) {
16449                 synchronized (this) {
16450                     final long cachedKb = memInfo.getCachedSizeKb();
16451                     final long freeKb = memInfo.getFreeSizeKb();
16452                     final long zramKb = memInfo.getZramTotalSizeKb();
16453                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16454                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16455                             kernelKb*1024, nativeProcTotalPss*1024);
16456                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16457                             nativeProcTotalPss);
16458                 }
16459             }
16460             if (!brief) {
16461                 if (!isCompact) {
16462                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16463                     pw.print(" (status ");
16464                     switch (mLastMemoryLevel) {
16465                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16466                             pw.println("normal)");
16467                             break;
16468                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16469                             pw.println("moderate)");
16470                             break;
16471                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16472                             pw.println("low)");
16473                             break;
16474                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16475                             pw.println("critical)");
16476                             break;
16477                         default:
16478                             pw.print(mLastMemoryLevel);
16479                             pw.println(")");
16480                             break;
16481                     }
16482                     pw.print(" Free RAM: ");
16483                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16484                             + memInfo.getFreeSizeKb()));
16485                     pw.print(" (");
16486                     pw.print(stringifyKBSize(cachedPss));
16487                     pw.print(" cached pss + ");
16488                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16489                     pw.print(" cached kernel + ");
16490                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16491                     pw.println(" free)");
16492                 } else {
16493                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16494                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16495                             + memInfo.getFreeSizeKb()); pw.print(",");
16496                     pw.println(totalPss - cachedPss);
16497                 }
16498             }
16499             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16500                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16501                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16502             if (!isCompact) {
16503                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16504                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16505                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16506                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16507                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16508             } else {
16509                 pw.print("lostram,"); pw.println(lostRAM);
16510             }
16511             if (!brief) {
16512                 if (memInfo.getZramTotalSizeKb() != 0) {
16513                     if (!isCompact) {
16514                         pw.print("     ZRAM: ");
16515                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16516                                 pw.print(" physical used for ");
16517                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16518                                         - memInfo.getSwapFreeSizeKb()));
16519                                 pw.print(" in swap (");
16520                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16521                                 pw.println(" total swap)");
16522                     } else {
16523                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16524                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16525                                 pw.println(memInfo.getSwapFreeSizeKb());
16526                     }
16527                 }
16528                 final long[] ksm = getKsmInfo();
16529                 if (!isCompact) {
16530                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16531                             || ksm[KSM_VOLATILE] != 0) {
16532                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16533                                 pw.print(" saved from shared ");
16534                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16535                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16536                                 pw.print(" unshared; ");
16537                                 pw.print(stringifyKBSize(
16538                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16539                     }
16540                     pw.print("   Tuning: ");
16541                     pw.print(ActivityManager.staticGetMemoryClass());
16542                     pw.print(" (large ");
16543                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16544                     pw.print("), oom ");
16545                     pw.print(stringifySize(
16546                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16547                     pw.print(", restore limit ");
16548                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16549                     if (ActivityManager.isLowRamDeviceStatic()) {
16550                         pw.print(" (low-ram)");
16551                     }
16552                     if (ActivityManager.isHighEndGfx()) {
16553                         pw.print(" (high-end-gfx)");
16554                     }
16555                     pw.println();
16556                 } else {
16557                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16558                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16559                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16560                     pw.print("tuning,");
16561                     pw.print(ActivityManager.staticGetMemoryClass());
16562                     pw.print(',');
16563                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16564                     pw.print(',');
16565                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16566                     if (ActivityManager.isLowRamDeviceStatic()) {
16567                         pw.print(",low-ram");
16568                     }
16569                     if (ActivityManager.isHighEndGfx()) {
16570                         pw.print(",high-end-gfx");
16571                     }
16572                     pw.println();
16573                 }
16574             }
16575         }
16576     }
16577
16578     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16579             long memtrack, String name) {
16580         sb.append("  ");
16581         sb.append(ProcessList.makeOomAdjString(oomAdj));
16582         sb.append(' ');
16583         sb.append(ProcessList.makeProcStateString(procState));
16584         sb.append(' ');
16585         ProcessList.appendRamKb(sb, pss);
16586         sb.append(": ");
16587         sb.append(name);
16588         if (memtrack > 0) {
16589             sb.append(" (");
16590             sb.append(stringifyKBSize(memtrack));
16591             sb.append(" memtrack)");
16592         }
16593     }
16594
16595     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16596         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16597         sb.append(" (pid ");
16598         sb.append(mi.pid);
16599         sb.append(") ");
16600         sb.append(mi.adjType);
16601         sb.append('\n');
16602         if (mi.adjReason != null) {
16603             sb.append("                      ");
16604             sb.append(mi.adjReason);
16605             sb.append('\n');
16606         }
16607     }
16608
16609     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16610         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16611         for (int i=0, N=memInfos.size(); i<N; i++) {
16612             ProcessMemInfo mi = memInfos.get(i);
16613             infoMap.put(mi.pid, mi);
16614         }
16615         updateCpuStatsNow();
16616         long[] memtrackTmp = new long[1];
16617         final List<ProcessCpuTracker.Stats> stats;
16618         // Get a list of Stats that have vsize > 0
16619         synchronized (mProcessCpuTracker) {
16620             stats = mProcessCpuTracker.getStats((st) -> {
16621                 return st.vsize > 0;
16622             });
16623         }
16624         final int statsCount = stats.size();
16625         for (int i = 0; i < statsCount; i++) {
16626             ProcessCpuTracker.Stats st = stats.get(i);
16627             long pss = Debug.getPss(st.pid, null, memtrackTmp);
16628             if (pss > 0) {
16629                 if (infoMap.indexOfKey(st.pid) < 0) {
16630                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16631                             ProcessList.NATIVE_ADJ, -1, "native", null);
16632                     mi.pss = pss;
16633                     mi.memtrack = memtrackTmp[0];
16634                     memInfos.add(mi);
16635                 }
16636             }
16637         }
16638
16639         long totalPss = 0;
16640         long totalMemtrack = 0;
16641         for (int i=0, N=memInfos.size(); i<N; i++) {
16642             ProcessMemInfo mi = memInfos.get(i);
16643             if (mi.pss == 0) {
16644                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16645                 mi.memtrack = memtrackTmp[0];
16646             }
16647             totalPss += mi.pss;
16648             totalMemtrack += mi.memtrack;
16649         }
16650         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16651             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16652                 if (lhs.oomAdj != rhs.oomAdj) {
16653                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16654                 }
16655                 if (lhs.pss != rhs.pss) {
16656                     return lhs.pss < rhs.pss ? 1 : -1;
16657                 }
16658                 return 0;
16659             }
16660         });
16661
16662         StringBuilder tag = new StringBuilder(128);
16663         StringBuilder stack = new StringBuilder(128);
16664         tag.append("Low on memory -- ");
16665         appendMemBucket(tag, totalPss, "total", false);
16666         appendMemBucket(stack, totalPss, "total", true);
16667
16668         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16669         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16670         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16671
16672         boolean firstLine = true;
16673         int lastOomAdj = Integer.MIN_VALUE;
16674         long extraNativeRam = 0;
16675         long extraNativeMemtrack = 0;
16676         long cachedPss = 0;
16677         for (int i=0, N=memInfos.size(); i<N; i++) {
16678             ProcessMemInfo mi = memInfos.get(i);
16679
16680             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16681                 cachedPss += mi.pss;
16682             }
16683
16684             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16685                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16686                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16687                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16688                 if (lastOomAdj != mi.oomAdj) {
16689                     lastOomAdj = mi.oomAdj;
16690                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16691                         tag.append(" / ");
16692                     }
16693                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16694                         if (firstLine) {
16695                             stack.append(":");
16696                             firstLine = false;
16697                         }
16698                         stack.append("\n\t at ");
16699                     } else {
16700                         stack.append("$");
16701                     }
16702                 } else {
16703                     tag.append(" ");
16704                     stack.append("$");
16705                 }
16706                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16707                     appendMemBucket(tag, mi.pss, mi.name, false);
16708                 }
16709                 appendMemBucket(stack, mi.pss, mi.name, true);
16710                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16711                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16712                     stack.append("(");
16713                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16714                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16715                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16716                             stack.append(":");
16717                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16718                         }
16719                     }
16720                     stack.append(")");
16721                 }
16722             }
16723
16724             appendMemInfo(fullNativeBuilder, mi);
16725             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16726                 // The short form only has native processes that are >= 512K.
16727                 if (mi.pss >= 512) {
16728                     appendMemInfo(shortNativeBuilder, mi);
16729                 } else {
16730                     extraNativeRam += mi.pss;
16731                     extraNativeMemtrack += mi.memtrack;
16732                 }
16733             } else {
16734                 // Short form has all other details, but if we have collected RAM
16735                 // from smaller native processes let's dump a summary of that.
16736                 if (extraNativeRam > 0) {
16737                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16738                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16739                     shortNativeBuilder.append('\n');
16740                     extraNativeRam = 0;
16741                 }
16742                 appendMemInfo(fullJavaBuilder, mi);
16743             }
16744         }
16745
16746         fullJavaBuilder.append("           ");
16747         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16748         fullJavaBuilder.append(": TOTAL");
16749         if (totalMemtrack > 0) {
16750             fullJavaBuilder.append(" (");
16751             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16752             fullJavaBuilder.append(" memtrack)");
16753         } else {
16754         }
16755         fullJavaBuilder.append("\n");
16756
16757         MemInfoReader memInfo = new MemInfoReader();
16758         memInfo.readMemInfo();
16759         final long[] infos = memInfo.getRawInfo();
16760
16761         StringBuilder memInfoBuilder = new StringBuilder(1024);
16762         Debug.getMemInfo(infos);
16763         memInfoBuilder.append("  MemInfo: ");
16764         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16765         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16766         memInfoBuilder.append(stringifyKBSize(
16767                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16768         memInfoBuilder.append(stringifyKBSize(
16769                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16770         memInfoBuilder.append(stringifyKBSize(
16771                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16772         memInfoBuilder.append("           ");
16773         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16774         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16775         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16776         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16777         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16778             memInfoBuilder.append("  ZRAM: ");
16779             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16780             memInfoBuilder.append(" RAM, ");
16781             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16782             memInfoBuilder.append(" swap total, ");
16783             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16784             memInfoBuilder.append(" swap free\n");
16785         }
16786         final long[] ksm = getKsmInfo();
16787         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16788                 || ksm[KSM_VOLATILE] != 0) {
16789             memInfoBuilder.append("  KSM: ");
16790             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16791             memInfoBuilder.append(" saved from shared ");
16792             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16793             memInfoBuilder.append("\n       ");
16794             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16795             memInfoBuilder.append(" unshared; ");
16796             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16797             memInfoBuilder.append(" volatile\n");
16798         }
16799         memInfoBuilder.append("  Free RAM: ");
16800         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16801                 + memInfo.getFreeSizeKb()));
16802         memInfoBuilder.append("\n");
16803         memInfoBuilder.append("  Used RAM: ");
16804         memInfoBuilder.append(stringifyKBSize(
16805                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16806         memInfoBuilder.append("\n");
16807         memInfoBuilder.append("  Lost RAM: ");
16808         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16809                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16810                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16811         memInfoBuilder.append("\n");
16812         Slog.i(TAG, "Low on memory:");
16813         Slog.i(TAG, shortNativeBuilder.toString());
16814         Slog.i(TAG, fullJavaBuilder.toString());
16815         Slog.i(TAG, memInfoBuilder.toString());
16816
16817         StringBuilder dropBuilder = new StringBuilder(1024);
16818         /*
16819         StringWriter oomSw = new StringWriter();
16820         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16821         StringWriter catSw = new StringWriter();
16822         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16823         String[] emptyArgs = new String[] { };
16824         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16825         oomPw.flush();
16826         String oomString = oomSw.toString();
16827         */
16828         dropBuilder.append("Low on memory:");
16829         dropBuilder.append(stack);
16830         dropBuilder.append('\n');
16831         dropBuilder.append(fullNativeBuilder);
16832         dropBuilder.append(fullJavaBuilder);
16833         dropBuilder.append('\n');
16834         dropBuilder.append(memInfoBuilder);
16835         dropBuilder.append('\n');
16836         /*
16837         dropBuilder.append(oomString);
16838         dropBuilder.append('\n');
16839         */
16840         StringWriter catSw = new StringWriter();
16841         synchronized (ActivityManagerService.this) {
16842             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16843             String[] emptyArgs = new String[] { };
16844             catPw.println();
16845             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16846             catPw.println();
16847             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16848                     false, null).dumpLocked();
16849             catPw.println();
16850             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16851             catPw.flush();
16852         }
16853         dropBuilder.append(catSw.toString());
16854         addErrorToDropBox("lowmem", null, "system_server", null,
16855                 null, tag.toString(), dropBuilder.toString(), null, null);
16856         //Slog.i(TAG, "Sent to dropbox:");
16857         //Slog.i(TAG, dropBuilder.toString());
16858         synchronized (ActivityManagerService.this) {
16859             long now = SystemClock.uptimeMillis();
16860             if (mLastMemUsageReportTime < now) {
16861                 mLastMemUsageReportTime = now;
16862             }
16863         }
16864     }
16865
16866     /**
16867      * Searches array of arguments for the specified string
16868      * @param args array of argument strings
16869      * @param value value to search for
16870      * @return true if the value is contained in the array
16871      */
16872     private static boolean scanArgs(String[] args, String value) {
16873         if (args != null) {
16874             for (String arg : args) {
16875                 if (value.equals(arg)) {
16876                     return true;
16877                 }
16878             }
16879         }
16880         return false;
16881     }
16882
16883     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16884             ContentProviderRecord cpr, boolean always) {
16885         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16886
16887         if (!inLaunching || always) {
16888             synchronized (cpr) {
16889                 cpr.launchingApp = null;
16890                 cpr.notifyAll();
16891             }
16892             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16893             String names[] = cpr.info.authority.split(";");
16894             for (int j = 0; j < names.length; j++) {
16895                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16896             }
16897         }
16898
16899         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16900             ContentProviderConnection conn = cpr.connections.get(i);
16901             if (conn.waiting) {
16902                 // If this connection is waiting for the provider, then we don't
16903                 // need to mess with its process unless we are always removing
16904                 // or for some reason the provider is not currently launching.
16905                 if (inLaunching && !always) {
16906                     continue;
16907                 }
16908             }
16909             ProcessRecord capp = conn.client;
16910             conn.dead = true;
16911             if (conn.stableCount > 0) {
16912                 if (!capp.persistent && capp.thread != null
16913                         && capp.pid != 0
16914                         && capp.pid != MY_PID) {
16915                     capp.kill("depends on provider "
16916                             + cpr.name.flattenToShortString()
16917                             + " in dying proc " + (proc != null ? proc.processName : "??")
16918                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16919                 }
16920             } else if (capp.thread != null && conn.provider.provider != null) {
16921                 try {
16922                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16923                 } catch (RemoteException e) {
16924                 }
16925                 // In the protocol here, we don't expect the client to correctly
16926                 // clean up this connection, we'll just remove it.
16927                 cpr.connections.remove(i);
16928                 if (conn.client.conProviders.remove(conn)) {
16929                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16930                 }
16931             }
16932         }
16933
16934         if (inLaunching && always) {
16935             mLaunchingProviders.remove(cpr);
16936         }
16937         return inLaunching;
16938     }
16939
16940     /**
16941      * Main code for cleaning up a process when it has gone away.  This is
16942      * called both as a result of the process dying, or directly when stopping
16943      * a process when running in single process mode.
16944      *
16945      * @return Returns true if the given process has been restarted, so the
16946      * app that was passed in must remain on the process lists.
16947      */
16948     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16949             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16950         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16951         if (index >= 0) {
16952             removeLruProcessLocked(app);
16953             ProcessList.remove(app.pid);
16954         }
16955
16956         mProcessesToGc.remove(app);
16957         mPendingPssProcesses.remove(app);
16958
16959         // Dismiss any open dialogs.
16960         if (app.crashDialog != null && !app.forceCrashReport) {
16961             app.crashDialog.dismiss();
16962             app.crashDialog = null;
16963         }
16964         if (app.anrDialog != null) {
16965             app.anrDialog.dismiss();
16966             app.anrDialog = null;
16967         }
16968         if (app.waitDialog != null) {
16969             app.waitDialog.dismiss();
16970             app.waitDialog = null;
16971         }
16972
16973         app.crashing = false;
16974         app.notResponding = false;
16975
16976         app.resetPackageList(mProcessStats);
16977         app.unlinkDeathRecipient();
16978         app.makeInactive(mProcessStats);
16979         app.waitingToKill = null;
16980         app.forcingToForeground = null;
16981         updateProcessForegroundLocked(app, false, false);
16982         app.foregroundActivities = false;
16983         app.hasShownUi = false;
16984         app.treatLikeActivity = false;
16985         app.hasAboveClient = false;
16986         app.hasClientActivities = false;
16987
16988         mServices.killServicesLocked(app, allowRestart);
16989
16990         boolean restart = false;
16991
16992         // Remove published content providers.
16993         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16994             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16995             final boolean always = app.bad || !allowRestart;
16996             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16997             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16998                 // We left the provider in the launching list, need to
16999                 // restart it.
17000                 restart = true;
17001             }
17002
17003             cpr.provider = null;
17004             cpr.proc = null;
17005         }
17006         app.pubProviders.clear();
17007
17008         // Take care of any launching providers waiting for this process.
17009         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17010             restart = true;
17011         }
17012
17013         // Unregister from connected content providers.
17014         if (!app.conProviders.isEmpty()) {
17015             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17016                 ContentProviderConnection conn = app.conProviders.get(i);
17017                 conn.provider.connections.remove(conn);
17018                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17019                         conn.provider.name);
17020             }
17021             app.conProviders.clear();
17022         }
17023
17024         // At this point there may be remaining entries in mLaunchingProviders
17025         // where we were the only one waiting, so they are no longer of use.
17026         // Look for these and clean up if found.
17027         // XXX Commented out for now.  Trying to figure out a way to reproduce
17028         // the actual situation to identify what is actually going on.
17029         if (false) {
17030             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17031                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17032                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17033                     synchronized (cpr) {
17034                         cpr.launchingApp = null;
17035                         cpr.notifyAll();
17036                     }
17037                 }
17038             }
17039         }
17040
17041         skipCurrentReceiverLocked(app);
17042
17043         // Unregister any receivers.
17044         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17045             removeReceiverLocked(app.receivers.valueAt(i));
17046         }
17047         app.receivers.clear();
17048
17049         // If the app is undergoing backup, tell the backup manager about it
17050         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17051             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17052                     + mBackupTarget.appInfo + " died during backup");
17053             try {
17054                 IBackupManager bm = IBackupManager.Stub.asInterface(
17055                         ServiceManager.getService(Context.BACKUP_SERVICE));
17056                 bm.agentDisconnected(app.info.packageName);
17057             } catch (RemoteException e) {
17058                 // can't happen; backup manager is local
17059             }
17060         }
17061
17062         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17063             ProcessChangeItem item = mPendingProcessChanges.get(i);
17064             if (item.pid == app.pid) {
17065                 mPendingProcessChanges.remove(i);
17066                 mAvailProcessChanges.add(item);
17067             }
17068         }
17069         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17070                 null).sendToTarget();
17071
17072         // If the caller is restarting this app, then leave it in its
17073         // current lists and let the caller take care of it.
17074         if (restarting) {
17075             return false;
17076         }
17077
17078         if (!app.persistent || app.isolated) {
17079             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17080                     "Removing non-persistent process during cleanup: " + app);
17081             if (!replacingPid) {
17082                 removeProcessNameLocked(app.processName, app.uid, app);
17083             }
17084             if (mHeavyWeightProcess == app) {
17085                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17086                         mHeavyWeightProcess.userId, 0));
17087                 mHeavyWeightProcess = null;
17088             }
17089         } else if (!app.removed) {
17090             // This app is persistent, so we need to keep its record around.
17091             // If it is not already on the pending app list, add it there
17092             // and start a new process for it.
17093             if (mPersistentStartingProcesses.indexOf(app) < 0) {
17094                 mPersistentStartingProcesses.add(app);
17095                 restart = true;
17096             }
17097         }
17098         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17099                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17100         mProcessesOnHold.remove(app);
17101
17102         if (app == mHomeProcess) {
17103             mHomeProcess = null;
17104         }
17105         if (app == mPreviousProcess) {
17106             mPreviousProcess = null;
17107         }
17108
17109         if (restart && !app.isolated) {
17110             // We have components that still need to be running in the
17111             // process, so re-launch it.
17112             if (index < 0) {
17113                 ProcessList.remove(app.pid);
17114             }
17115             addProcessNameLocked(app);
17116             startProcessLocked(app, "restart", app.processName);
17117             return true;
17118         } else if (app.pid > 0 && app.pid != MY_PID) {
17119             // Goodbye!
17120             boolean removed;
17121             synchronized (mPidsSelfLocked) {
17122                 mPidsSelfLocked.remove(app.pid);
17123                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17124             }
17125             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17126             if (app.isolated) {
17127                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17128             }
17129             app.setPid(0);
17130         }
17131         return false;
17132     }
17133
17134     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17135         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17136             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17137             if (cpr.launchingApp == app) {
17138                 return true;
17139             }
17140         }
17141         return false;
17142     }
17143
17144     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17145         // Look through the content providers we are waiting to have launched,
17146         // and if any run in this process then either schedule a restart of
17147         // the process or kill the client waiting for it if this process has
17148         // gone bad.
17149         boolean restart = false;
17150         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17151             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17152             if (cpr.launchingApp == app) {
17153                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17154                     restart = true;
17155                 } else {
17156                     removeDyingProviderLocked(app, cpr, true);
17157                 }
17158             }
17159         }
17160         return restart;
17161     }
17162
17163     // =========================================================
17164     // SERVICES
17165     // =========================================================
17166
17167     @Override
17168     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17169             int flags) {
17170         enforceNotIsolatedCaller("getServices");
17171         synchronized (this) {
17172             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17173         }
17174     }
17175
17176     @Override
17177     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17178         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17179         synchronized (this) {
17180             return mServices.getRunningServiceControlPanelLocked(name);
17181         }
17182     }
17183
17184     @Override
17185     public ComponentName startService(IApplicationThread caller, Intent service,
17186             String resolvedType, String callingPackage, int userId)
17187             throws TransactionTooLargeException {
17188         enforceNotIsolatedCaller("startService");
17189         // Refuse possible leaked file descriptors
17190         if (service != null && service.hasFileDescriptors() == true) {
17191             throw new IllegalArgumentException("File descriptors passed in Intent");
17192         }
17193
17194         if (callingPackage == null) {
17195             throw new IllegalArgumentException("callingPackage cannot be null");
17196         }
17197
17198         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17199                 "startService: " + service + " type=" + resolvedType);
17200         synchronized(this) {
17201             final int callingPid = Binder.getCallingPid();
17202             final int callingUid = Binder.getCallingUid();
17203             final long origId = Binder.clearCallingIdentity();
17204             ComponentName res = mServices.startServiceLocked(caller, service,
17205                     resolvedType, callingPid, callingUid, callingPackage, userId);
17206             Binder.restoreCallingIdentity(origId);
17207             return res;
17208         }
17209     }
17210
17211     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17212             String callingPackage, int userId)
17213             throws TransactionTooLargeException {
17214         synchronized(this) {
17215             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17216                     "startServiceInPackage: " + service + " type=" + resolvedType);
17217             final long origId = Binder.clearCallingIdentity();
17218             ComponentName res = mServices.startServiceLocked(null, service,
17219                     resolvedType, -1, uid, callingPackage, userId);
17220             Binder.restoreCallingIdentity(origId);
17221             return res;
17222         }
17223     }
17224
17225     @Override
17226     public int stopService(IApplicationThread caller, Intent service,
17227             String resolvedType, int userId) {
17228         enforceNotIsolatedCaller("stopService");
17229         // Refuse possible leaked file descriptors
17230         if (service != null && service.hasFileDescriptors() == true) {
17231             throw new IllegalArgumentException("File descriptors passed in Intent");
17232         }
17233
17234         synchronized(this) {
17235             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17236         }
17237     }
17238
17239     @Override
17240     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17241         enforceNotIsolatedCaller("peekService");
17242         // Refuse possible leaked file descriptors
17243         if (service != null && service.hasFileDescriptors() == true) {
17244             throw new IllegalArgumentException("File descriptors passed in Intent");
17245         }
17246
17247         if (callingPackage == null) {
17248             throw new IllegalArgumentException("callingPackage cannot be null");
17249         }
17250
17251         synchronized(this) {
17252             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17253         }
17254     }
17255
17256     @Override
17257     public boolean stopServiceToken(ComponentName className, IBinder token,
17258             int startId) {
17259         synchronized(this) {
17260             return mServices.stopServiceTokenLocked(className, token, startId);
17261         }
17262     }
17263
17264     @Override
17265     public void setServiceForeground(ComponentName className, IBinder token,
17266             int id, Notification notification, int flags) {
17267         synchronized(this) {
17268             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17269         }
17270     }
17271
17272     @Override
17273     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17274             boolean requireFull, String name, String callerPackage) {
17275         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17276                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17277     }
17278
17279     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17280             String className, int flags) {
17281         boolean result = false;
17282         // For apps that don't have pre-defined UIDs, check for permission
17283         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17284             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17285                 if (ActivityManager.checkUidPermission(
17286                         INTERACT_ACROSS_USERS,
17287                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17288                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17289                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17290                             + " requests FLAG_SINGLE_USER, but app does not hold "
17291                             + INTERACT_ACROSS_USERS;
17292                     Slog.w(TAG, msg);
17293                     throw new SecurityException(msg);
17294                 }
17295                 // Permission passed
17296                 result = true;
17297             }
17298         } else if ("system".equals(componentProcessName)) {
17299             result = true;
17300         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17301             // Phone app and persistent apps are allowed to export singleuser providers.
17302             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17303                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17304         }
17305         if (DEBUG_MU) Slog.v(TAG_MU,
17306                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17307                 + Integer.toHexString(flags) + ") = " + result);
17308         return result;
17309     }
17310
17311     /**
17312      * Checks to see if the caller is in the same app as the singleton
17313      * component, or the component is in a special app. It allows special apps
17314      * to export singleton components but prevents exporting singleton
17315      * components for regular apps.
17316      */
17317     boolean isValidSingletonCall(int callingUid, int componentUid) {
17318         int componentAppId = UserHandle.getAppId(componentUid);
17319         return UserHandle.isSameApp(callingUid, componentUid)
17320                 || componentAppId == Process.SYSTEM_UID
17321                 || componentAppId == Process.PHONE_UID
17322                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17323                         == PackageManager.PERMISSION_GRANTED;
17324     }
17325
17326     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17327             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17328             int userId) throws TransactionTooLargeException {
17329         enforceNotIsolatedCaller("bindService");
17330
17331         // Refuse possible leaked file descriptors
17332         if (service != null && service.hasFileDescriptors() == true) {
17333             throw new IllegalArgumentException("File descriptors passed in Intent");
17334         }
17335
17336         if (callingPackage == null) {
17337             throw new IllegalArgumentException("callingPackage cannot be null");
17338         }
17339
17340         synchronized(this) {
17341             return mServices.bindServiceLocked(caller, token, service,
17342                     resolvedType, connection, flags, callingPackage, userId);
17343         }
17344     }
17345
17346     public boolean unbindService(IServiceConnection connection) {
17347         synchronized (this) {
17348             return mServices.unbindServiceLocked(connection);
17349         }
17350     }
17351
17352     public void publishService(IBinder token, Intent intent, IBinder service) {
17353         // Refuse possible leaked file descriptors
17354         if (intent != null && intent.hasFileDescriptors() == true) {
17355             throw new IllegalArgumentException("File descriptors passed in Intent");
17356         }
17357
17358         synchronized(this) {
17359             if (!(token instanceof ServiceRecord)) {
17360                 throw new IllegalArgumentException("Invalid service token");
17361             }
17362             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17363         }
17364     }
17365
17366     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17367         // Refuse possible leaked file descriptors
17368         if (intent != null && intent.hasFileDescriptors() == true) {
17369             throw new IllegalArgumentException("File descriptors passed in Intent");
17370         }
17371
17372         synchronized(this) {
17373             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17374         }
17375     }
17376
17377     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17378         synchronized(this) {
17379             if (!(token instanceof ServiceRecord)) {
17380                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17381                 throw new IllegalArgumentException("Invalid service token");
17382             }
17383             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17384         }
17385     }
17386
17387     // =========================================================
17388     // BACKUP AND RESTORE
17389     // =========================================================
17390
17391     // Cause the target app to be launched if necessary and its backup agent
17392     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17393     // activity manager to announce its creation.
17394     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17395         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17396         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17397
17398         IPackageManager pm = AppGlobals.getPackageManager();
17399         ApplicationInfo app = null;
17400         try {
17401             app = pm.getApplicationInfo(packageName, 0, userId);
17402         } catch (RemoteException e) {
17403             // can't happen; package manager is process-local
17404         }
17405         if (app == null) {
17406             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17407             return false;
17408         }
17409
17410         synchronized(this) {
17411             // !!! TODO: currently no check here that we're already bound
17412             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17413             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17414             synchronized (stats) {
17415                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17416             }
17417
17418             // Backup agent is now in use, its package can't be stopped.
17419             try {
17420                 AppGlobals.getPackageManager().setPackageStoppedState(
17421                         app.packageName, false, UserHandle.getUserId(app.uid));
17422             } catch (RemoteException e) {
17423             } catch (IllegalArgumentException e) {
17424                 Slog.w(TAG, "Failed trying to unstop package "
17425                         + app.packageName + ": " + e);
17426             }
17427
17428             BackupRecord r = new BackupRecord(ss, app, backupMode);
17429             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17430                     ? new ComponentName(app.packageName, app.backupAgentName)
17431                     : new ComponentName("android", "FullBackupAgent");
17432             // startProcessLocked() returns existing proc's record if it's already running
17433             ProcessRecord proc = startProcessLocked(app.processName, app,
17434                     false, 0, "backup", hostingName, false, false, false);
17435             if (proc == null) {
17436                 Slog.e(TAG, "Unable to start backup agent process " + r);
17437                 return false;
17438             }
17439
17440             // If the app is a regular app (uid >= 10000) and not the system server or phone
17441             // process, etc, then mark it as being in full backup so that certain calls to the
17442             // process can be blocked. This is not reset to false anywhere because we kill the
17443             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17444             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17445                 proc.inFullBackup = true;
17446             }
17447             r.app = proc;
17448             mBackupTarget = r;
17449             mBackupAppName = app.packageName;
17450
17451             // Try not to kill the process during backup
17452             updateOomAdjLocked(proc);
17453
17454             // If the process is already attached, schedule the creation of the backup agent now.
17455             // If it is not yet live, this will be done when it attaches to the framework.
17456             if (proc.thread != null) {
17457                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17458                 try {
17459                     proc.thread.scheduleCreateBackupAgent(app,
17460                             compatibilityInfoForPackageLocked(app), backupMode);
17461                 } catch (RemoteException e) {
17462                     // Will time out on the backup manager side
17463                 }
17464             } else {
17465                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17466             }
17467             // Invariants: at this point, the target app process exists and the application
17468             // is either already running or in the process of coming up.  mBackupTarget and
17469             // mBackupAppName describe the app, so that when it binds back to the AM we
17470             // know that it's scheduled for a backup-agent operation.
17471         }
17472
17473         return true;
17474     }
17475
17476     @Override
17477     public void clearPendingBackup() {
17478         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17479         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17480
17481         synchronized (this) {
17482             mBackupTarget = null;
17483             mBackupAppName = null;
17484         }
17485     }
17486
17487     // A backup agent has just come up
17488     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17489         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17490                 + " = " + agent);
17491
17492         synchronized(this) {
17493             if (!agentPackageName.equals(mBackupAppName)) {
17494                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17495                 return;
17496             }
17497         }
17498
17499         long oldIdent = Binder.clearCallingIdentity();
17500         try {
17501             IBackupManager bm = IBackupManager.Stub.asInterface(
17502                     ServiceManager.getService(Context.BACKUP_SERVICE));
17503             bm.agentConnected(agentPackageName, agent);
17504         } catch (RemoteException e) {
17505             // can't happen; the backup manager service is local
17506         } catch (Exception e) {
17507             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17508             e.printStackTrace();
17509         } finally {
17510             Binder.restoreCallingIdentity(oldIdent);
17511         }
17512     }
17513
17514     // done with this agent
17515     public void unbindBackupAgent(ApplicationInfo appInfo) {
17516         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17517         if (appInfo == null) {
17518             Slog.w(TAG, "unbind backup agent for null app");
17519             return;
17520         }
17521
17522         synchronized(this) {
17523             try {
17524                 if (mBackupAppName == null) {
17525                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17526                     return;
17527                 }
17528
17529                 if (!mBackupAppName.equals(appInfo.packageName)) {
17530                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17531                     return;
17532                 }
17533
17534                 // Not backing this app up any more; reset its OOM adjustment
17535                 final ProcessRecord proc = mBackupTarget.app;
17536                 updateOomAdjLocked(proc);
17537
17538                 // If the app crashed during backup, 'thread' will be null here
17539                 if (proc.thread != null) {
17540                     try {
17541                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17542                                 compatibilityInfoForPackageLocked(appInfo));
17543                     } catch (Exception e) {
17544                         Slog.e(TAG, "Exception when unbinding backup agent:");
17545                         e.printStackTrace();
17546                     }
17547                 }
17548             } finally {
17549                 mBackupTarget = null;
17550                 mBackupAppName = null;
17551             }
17552         }
17553     }
17554     // =========================================================
17555     // BROADCASTS
17556     // =========================================================
17557
17558     boolean isPendingBroadcastProcessLocked(int pid) {
17559         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17560                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17561     }
17562
17563     void skipPendingBroadcastLocked(int pid) {
17564             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17565             for (BroadcastQueue queue : mBroadcastQueues) {
17566                 queue.skipPendingBroadcastLocked(pid);
17567             }
17568     }
17569
17570     // The app just attached; send any pending broadcasts that it should receive
17571     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17572         boolean didSomething = false;
17573         for (BroadcastQueue queue : mBroadcastQueues) {
17574             didSomething |= queue.sendPendingBroadcastsLocked(app);
17575         }
17576         return didSomething;
17577     }
17578
17579     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17580             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17581         enforceNotIsolatedCaller("registerReceiver");
17582         ArrayList<Intent> stickyIntents = null;
17583         ProcessRecord callerApp = null;
17584         int callingUid;
17585         int callingPid;
17586         synchronized(this) {
17587             if (caller != null) {
17588                 callerApp = getRecordForAppLocked(caller);
17589                 if (callerApp == null) {
17590                     throw new SecurityException(
17591                             "Unable to find app for caller " + caller
17592                             + " (pid=" + Binder.getCallingPid()
17593                             + ") when registering receiver " + receiver);
17594                 }
17595                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17596                         !callerApp.pkgList.containsKey(callerPackage) &&
17597                         !"android".equals(callerPackage)) {
17598                     throw new SecurityException("Given caller package " + callerPackage
17599                             + " is not running in process " + callerApp);
17600                 }
17601                 callingUid = callerApp.info.uid;
17602                 callingPid = callerApp.pid;
17603             } else {
17604                 callerPackage = null;
17605                 callingUid = Binder.getCallingUid();
17606                 callingPid = Binder.getCallingPid();
17607             }
17608
17609             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17610                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17611
17612             Iterator<String> actions = filter.actionsIterator();
17613             if (actions == null) {
17614                 ArrayList<String> noAction = new ArrayList<String>(1);
17615                 noAction.add(null);
17616                 actions = noAction.iterator();
17617             }
17618
17619             // Collect stickies of users
17620             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17621             while (actions.hasNext()) {
17622                 String action = actions.next();
17623                 for (int id : userIds) {
17624                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17625                     if (stickies != null) {
17626                         ArrayList<Intent> intents = stickies.get(action);
17627                         if (intents != null) {
17628                             if (stickyIntents == null) {
17629                                 stickyIntents = new ArrayList<Intent>();
17630                             }
17631                             stickyIntents.addAll(intents);
17632                         }
17633                     }
17634                 }
17635             }
17636         }
17637
17638         ArrayList<Intent> allSticky = null;
17639         if (stickyIntents != null) {
17640             final ContentResolver resolver = mContext.getContentResolver();
17641             // Look for any matching sticky broadcasts...
17642             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17643                 Intent intent = stickyIntents.get(i);
17644                 // If intent has scheme "content", it will need to acccess
17645                 // provider that needs to lock mProviderMap in ActivityThread
17646                 // and also it may need to wait application response, so we
17647                 // cannot lock ActivityManagerService here.
17648                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17649                     if (allSticky == null) {
17650                         allSticky = new ArrayList<Intent>();
17651                     }
17652                     allSticky.add(intent);
17653                 }
17654             }
17655         }
17656
17657         // The first sticky in the list is returned directly back to the client.
17658         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17659         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17660         if (receiver == null) {
17661             return sticky;
17662         }
17663
17664         synchronized (this) {
17665             if (callerApp != null && (callerApp.thread == null
17666                     || callerApp.thread.asBinder() != caller.asBinder())) {
17667                 // Original caller already died
17668                 return null;
17669             }
17670             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17671             if (rl == null) {
17672                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17673                         userId, receiver);
17674                 if (rl.app != null) {
17675                     rl.app.receivers.add(rl);
17676                 } else {
17677                     try {
17678                         receiver.asBinder().linkToDeath(rl, 0);
17679                     } catch (RemoteException e) {
17680                         return sticky;
17681                     }
17682                     rl.linkedToDeath = true;
17683                 }
17684                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17685             } else if (rl.uid != callingUid) {
17686                 throw new IllegalArgumentException(
17687                         "Receiver requested to register for uid " + callingUid
17688                         + " was previously registered for uid " + rl.uid);
17689             } else if (rl.pid != callingPid) {
17690                 throw new IllegalArgumentException(
17691                         "Receiver requested to register for pid " + callingPid
17692                         + " was previously registered for pid " + rl.pid);
17693             } else if (rl.userId != userId) {
17694                 throw new IllegalArgumentException(
17695                         "Receiver requested to register for user " + userId
17696                         + " was previously registered for user " + rl.userId);
17697             }
17698             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17699                     permission, callingUid, userId);
17700             rl.add(bf);
17701             if (!bf.debugCheck()) {
17702                 Slog.w(TAG, "==> For Dynamic broadcast");
17703             }
17704             mReceiverResolver.addFilter(bf);
17705
17706             // Enqueue broadcasts for all existing stickies that match
17707             // this filter.
17708             if (allSticky != null) {
17709                 ArrayList receivers = new ArrayList();
17710                 receivers.add(bf);
17711
17712                 final int stickyCount = allSticky.size();
17713                 for (int i = 0; i < stickyCount; i++) {
17714                     Intent intent = allSticky.get(i);
17715                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17716                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17717                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17718                             null, 0, null, null, false, true, true, -1);
17719                     queue.enqueueParallelBroadcastLocked(r);
17720                     queue.scheduleBroadcastsLocked();
17721                 }
17722             }
17723
17724             return sticky;
17725         }
17726     }
17727
17728     public void unregisterReceiver(IIntentReceiver receiver) {
17729         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17730
17731         final long origId = Binder.clearCallingIdentity();
17732         try {
17733             boolean doTrim = false;
17734
17735             synchronized(this) {
17736                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17737                 if (rl != null) {
17738                     final BroadcastRecord r = rl.curBroadcast;
17739                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17740                         final boolean doNext = r.queue.finishReceiverLocked(
17741                                 r, r.resultCode, r.resultData, r.resultExtras,
17742                                 r.resultAbort, false);
17743                         if (doNext) {
17744                             doTrim = true;
17745                             r.queue.processNextBroadcast(false);
17746                         }
17747                     }
17748
17749                     if (rl.app != null) {
17750                         rl.app.receivers.remove(rl);
17751                     }
17752                     removeReceiverLocked(rl);
17753                     if (rl.linkedToDeath) {
17754                         rl.linkedToDeath = false;
17755                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17756                     }
17757                 }
17758             }
17759
17760             // If we actually concluded any broadcasts, we might now be able
17761             // to trim the recipients' apps from our working set
17762             if (doTrim) {
17763                 trimApplications();
17764                 return;
17765             }
17766
17767         } finally {
17768             Binder.restoreCallingIdentity(origId);
17769         }
17770     }
17771
17772     void removeReceiverLocked(ReceiverList rl) {
17773         mRegisteredReceivers.remove(rl.receiver.asBinder());
17774         for (int i = rl.size() - 1; i >= 0; i--) {
17775             mReceiverResolver.removeFilter(rl.get(i));
17776         }
17777     }
17778
17779     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17780         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17781             ProcessRecord r = mLruProcesses.get(i);
17782             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17783                 try {
17784                     r.thread.dispatchPackageBroadcast(cmd, packages);
17785                 } catch (RemoteException ex) {
17786                 }
17787             }
17788         }
17789     }
17790
17791     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17792             int callingUid, int[] users) {
17793         // TODO: come back and remove this assumption to triage all broadcasts
17794         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17795
17796         List<ResolveInfo> receivers = null;
17797         try {
17798             HashSet<ComponentName> singleUserReceivers = null;
17799             boolean scannedFirstReceivers = false;
17800             for (int user : users) {
17801                 // Skip users that have Shell restrictions, with exception of always permitted
17802                 // Shell broadcasts
17803                 if (callingUid == Process.SHELL_UID
17804                         && mUserController.hasUserRestriction(
17805                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17806                         && !isPermittedShellBroadcast(intent)) {
17807                     continue;
17808                 }
17809                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17810                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17811                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17812                     // If this is not the system user, we need to check for
17813                     // any receivers that should be filtered out.
17814                     for (int i=0; i<newReceivers.size(); i++) {
17815                         ResolveInfo ri = newReceivers.get(i);
17816                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17817                             newReceivers.remove(i);
17818                             i--;
17819                         }
17820                     }
17821                 }
17822                 if (newReceivers != null && newReceivers.size() == 0) {
17823                     newReceivers = null;
17824                 }
17825                 if (receivers == null) {
17826                     receivers = newReceivers;
17827                 } else if (newReceivers != null) {
17828                     // We need to concatenate the additional receivers
17829                     // found with what we have do far.  This would be easy,
17830                     // but we also need to de-dup any receivers that are
17831                     // singleUser.
17832                     if (!scannedFirstReceivers) {
17833                         // Collect any single user receivers we had already retrieved.
17834                         scannedFirstReceivers = true;
17835                         for (int i=0; i<receivers.size(); i++) {
17836                             ResolveInfo ri = receivers.get(i);
17837                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17838                                 ComponentName cn = new ComponentName(
17839                                         ri.activityInfo.packageName, ri.activityInfo.name);
17840                                 if (singleUserReceivers == null) {
17841                                     singleUserReceivers = new HashSet<ComponentName>();
17842                                 }
17843                                 singleUserReceivers.add(cn);
17844                             }
17845                         }
17846                     }
17847                     // Add the new results to the existing results, tracking
17848                     // and de-dupping single user receivers.
17849                     for (int i=0; i<newReceivers.size(); i++) {
17850                         ResolveInfo ri = newReceivers.get(i);
17851                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17852                             ComponentName cn = new ComponentName(
17853                                     ri.activityInfo.packageName, ri.activityInfo.name);
17854                             if (singleUserReceivers == null) {
17855                                 singleUserReceivers = new HashSet<ComponentName>();
17856                             }
17857                             if (!singleUserReceivers.contains(cn)) {
17858                                 singleUserReceivers.add(cn);
17859                                 receivers.add(ri);
17860                             }
17861                         } else {
17862                             receivers.add(ri);
17863                         }
17864                     }
17865                 }
17866             }
17867         } catch (RemoteException ex) {
17868             // pm is in same process, this will never happen.
17869         }
17870         return receivers;
17871     }
17872
17873     private boolean isPermittedShellBroadcast(Intent intent) {
17874         // remote bugreport should always be allowed to be taken
17875         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17876     }
17877
17878     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17879             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17880         final String action = intent.getAction();
17881         if (isProtectedBroadcast
17882                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17883                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17884                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17885                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17886                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17887                 || Intent.ACTION_MASTER_CLEAR.equals(action)
17888                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17889                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17890                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17891                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17892                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17893             // Broadcast is either protected, or it's a public action that
17894             // we've relaxed, so it's fine for system internals to send.
17895             return;
17896         }
17897
17898         // This broadcast may be a problem...  but there are often system components that
17899         // want to send an internal broadcast to themselves, which is annoying to have to
17900         // explicitly list each action as a protected broadcast, so we will check for that
17901         // one safe case and allow it: an explicit broadcast, only being received by something
17902         // that has protected itself.
17903         if (receivers != null && receivers.size() > 0
17904                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17905             boolean allProtected = true;
17906             for (int i = receivers.size()-1; i >= 0; i--) {
17907                 Object target = receivers.get(i);
17908                 if (target instanceof ResolveInfo) {
17909                     ResolveInfo ri = (ResolveInfo)target;
17910                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17911                         allProtected = false;
17912                         break;
17913                     }
17914                 } else {
17915                     BroadcastFilter bf = (BroadcastFilter)target;
17916                     if (bf.requiredPermission == null) {
17917                         allProtected = false;
17918                         break;
17919                     }
17920                 }
17921             }
17922             if (allProtected) {
17923                 // All safe!
17924                 return;
17925             }
17926         }
17927
17928         // The vast majority of broadcasts sent from system internals
17929         // should be protected to avoid security holes, so yell loudly
17930         // to ensure we examine these cases.
17931         if (callerApp != null) {
17932             Log.wtf(TAG, "Sending non-protected broadcast " + action
17933                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17934                     new Throwable());
17935         } else {
17936             Log.wtf(TAG, "Sending non-protected broadcast " + action
17937                             + " from system uid " + UserHandle.formatUid(callingUid)
17938                             + " pkg " + callerPackage,
17939                     new Throwable());
17940         }
17941     }
17942
17943     final int broadcastIntentLocked(ProcessRecord callerApp,
17944             String callerPackage, Intent intent, String resolvedType,
17945             IIntentReceiver resultTo, int resultCode, String resultData,
17946             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17947             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17948         intent = new Intent(intent);
17949
17950         // By default broadcasts do not go to stopped apps.
17951         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17952
17953         // If we have not finished booting, don't allow this to launch new processes.
17954         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17955             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17956         }
17957
17958         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17959                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17960                 + " ordered=" + ordered + " userid=" + userId);
17961         if ((resultTo != null) && !ordered) {
17962             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17963         }
17964
17965         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17966                 ALLOW_NON_FULL, "broadcast", callerPackage);
17967
17968         // Make sure that the user who is receiving this broadcast is running.
17969         // If not, we will just skip it. Make an exception for shutdown broadcasts
17970         // and upgrade steps.
17971
17972         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17973             if ((callingUid != Process.SYSTEM_UID
17974                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17975                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17976                 Slog.w(TAG, "Skipping broadcast of " + intent
17977                         + ": user " + userId + " is stopped");
17978                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17979             }
17980         }
17981
17982         BroadcastOptions brOptions = null;
17983         if (bOptions != null) {
17984             brOptions = new BroadcastOptions(bOptions);
17985             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17986                 // See if the caller is allowed to do this.  Note we are checking against
17987                 // the actual real caller (not whoever provided the operation as say a
17988                 // PendingIntent), because that who is actually supplied the arguments.
17989                 if (checkComponentPermission(
17990                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17991                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17992                         != PackageManager.PERMISSION_GRANTED) {
17993                     String msg = "Permission Denial: " + intent.getAction()
17994                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17995                             + ", uid=" + callingUid + ")"
17996                             + " requires "
17997                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17998                     Slog.w(TAG, msg);
17999                     throw new SecurityException(msg);
18000                 }
18001             }
18002         }
18003
18004         // Verify that protected broadcasts are only being sent by system code,
18005         // and that system code is only sending protected broadcasts.
18006         final String action = intent.getAction();
18007         final boolean isProtectedBroadcast;
18008         try {
18009             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18010         } catch (RemoteException e) {
18011             Slog.w(TAG, "Remote exception", e);
18012             return ActivityManager.BROADCAST_SUCCESS;
18013         }
18014
18015         final boolean isCallerSystem;
18016         switch (UserHandle.getAppId(callingUid)) {
18017             case Process.ROOT_UID:
18018             case Process.SYSTEM_UID:
18019             case Process.PHONE_UID:
18020             case Process.BLUETOOTH_UID:
18021             case Process.NFC_UID:
18022                 isCallerSystem = true;
18023                 break;
18024             default:
18025                 isCallerSystem = (callerApp != null) && callerApp.persistent;
18026                 break;
18027         }
18028
18029         // First line security check before anything else: stop non-system apps from
18030         // sending protected broadcasts.
18031         if (!isCallerSystem) {
18032             if (isProtectedBroadcast) {
18033                 String msg = "Permission Denial: not allowed to send broadcast "
18034                         + action + " from pid="
18035                         + callingPid + ", uid=" + callingUid;
18036                 Slog.w(TAG, msg);
18037                 throw new SecurityException(msg);
18038
18039             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18040                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18041                 // Special case for compatibility: we don't want apps to send this,
18042                 // but historically it has not been protected and apps may be using it
18043                 // to poke their own app widget.  So, instead of making it protected,
18044                 // just limit it to the caller.
18045                 if (callerPackage == null) {
18046                     String msg = "Permission Denial: not allowed to send broadcast "
18047                             + action + " from unknown caller.";
18048                     Slog.w(TAG, msg);
18049                     throw new SecurityException(msg);
18050                 } else if (intent.getComponent() != null) {
18051                     // They are good enough to send to an explicit component...  verify
18052                     // it is being sent to the calling app.
18053                     if (!intent.getComponent().getPackageName().equals(
18054                             callerPackage)) {
18055                         String msg = "Permission Denial: not allowed to send broadcast "
18056                                 + action + " to "
18057                                 + intent.getComponent().getPackageName() + " from "
18058                                 + callerPackage;
18059                         Slog.w(TAG, msg);
18060                         throw new SecurityException(msg);
18061                     }
18062                 } else {
18063                     // Limit broadcast to their own package.
18064                     intent.setPackage(callerPackage);
18065                 }
18066             }
18067         }
18068
18069         if (action != null) {
18070             switch (action) {
18071                 case Intent.ACTION_UID_REMOVED:
18072                 case Intent.ACTION_PACKAGE_REMOVED:
18073                 case Intent.ACTION_PACKAGE_CHANGED:
18074                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18075                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18076                 case Intent.ACTION_PACKAGES_SUSPENDED:
18077                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18078                     // Handle special intents: if this broadcast is from the package
18079                     // manager about a package being removed, we need to remove all of
18080                     // its activities from the history stack.
18081                     if (checkComponentPermission(
18082                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18083                             callingPid, callingUid, -1, true)
18084                             != PackageManager.PERMISSION_GRANTED) {
18085                         String msg = "Permission Denial: " + intent.getAction()
18086                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
18087                                 + ", uid=" + callingUid + ")"
18088                                 + " requires "
18089                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18090                         Slog.w(TAG, msg);
18091                         throw new SecurityException(msg);
18092                     }
18093                     switch (action) {
18094                         case Intent.ACTION_UID_REMOVED:
18095                             final Bundle intentExtras = intent.getExtras();
18096                             final int uid = intentExtras != null
18097                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18098                             if (uid >= 0) {
18099                                 mBatteryStatsService.removeUid(uid);
18100                                 mAppOpsService.uidRemoved(uid);
18101                             }
18102                             break;
18103                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18104                             // If resources are unavailable just force stop all those packages
18105                             // and flush the attribute cache as well.
18106                             String list[] =
18107                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18108                             if (list != null && list.length > 0) {
18109                                 for (int i = 0; i < list.length; i++) {
18110                                     forceStopPackageLocked(list[i], -1, false, true, true,
18111                                             false, false, userId, "storage unmount");
18112                                 }
18113                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18114                                 sendPackageBroadcastLocked(
18115                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18116                                         userId);
18117                             }
18118                             break;
18119                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18120                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18121                             break;
18122                         case Intent.ACTION_PACKAGE_REMOVED:
18123                         case Intent.ACTION_PACKAGE_CHANGED:
18124                             Uri data = intent.getData();
18125                             String ssp;
18126                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18127                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18128                                 final boolean replacing =
18129                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18130                                 final boolean killProcess =
18131                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18132                                 final boolean fullUninstall = removed && !replacing;
18133                                 if (removed) {
18134                                     if (killProcess) {
18135                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18136                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18137                                                 false, true, true, false, fullUninstall, userId,
18138                                                 removed ? "pkg removed" : "pkg changed");
18139                                     }
18140                                     final int cmd = killProcess
18141                                             ? IApplicationThread.PACKAGE_REMOVED
18142                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18143                                     sendPackageBroadcastLocked(cmd,
18144                                             new String[] {ssp}, userId);
18145                                     if (fullUninstall) {
18146                                         mAppOpsService.packageRemoved(
18147                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18148
18149                                         // Remove all permissions granted from/to this package
18150                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18151
18152                                         removeTasksByPackageNameLocked(ssp, userId);
18153
18154                                         // Hide the "unsupported display" dialog if necessary.
18155                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18156                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18157                                             mUnsupportedDisplaySizeDialog.dismiss();
18158                                             mUnsupportedDisplaySizeDialog = null;
18159                                         }
18160                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18161                                         mBatteryStatsService.notePackageUninstalled(ssp);
18162                                     }
18163                                 } else {
18164                                     if (killProcess) {
18165                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18166                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18167                                                 userId, ProcessList.INVALID_ADJ,
18168                                                 false, true, true, false, "change " + ssp);
18169                                     }
18170                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18171                                             intent.getStringArrayExtra(
18172                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18173                                 }
18174                             }
18175                             break;
18176                         case Intent.ACTION_PACKAGES_SUSPENDED:
18177                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18178                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18179                                     intent.getAction());
18180                             final String[] packageNames = intent.getStringArrayExtra(
18181                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18182                             final int userHandle = intent.getIntExtra(
18183                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18184
18185                             synchronized(ActivityManagerService.this) {
18186                                 mRecentTasks.onPackagesSuspendedChanged(
18187                                         packageNames, suspended, userHandle);
18188                             }
18189                             break;
18190                     }
18191                     break;
18192                 case Intent.ACTION_PACKAGE_REPLACED:
18193                 {
18194                     final Uri data = intent.getData();
18195                     final String ssp;
18196                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18197                         final ApplicationInfo aInfo =
18198                                 getPackageManagerInternalLocked().getApplicationInfo(
18199                                         ssp,
18200                                         userId);
18201                         if (aInfo == null) {
18202                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18203                                     + " ssp=" + ssp + " data=" + data);
18204                             return ActivityManager.BROADCAST_SUCCESS;
18205                         }
18206                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18207                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18208                                 new String[] {ssp}, userId);
18209                     }
18210                     break;
18211                 }
18212                 case Intent.ACTION_PACKAGE_ADDED:
18213                 {
18214                     // Special case for adding a package: by default turn on compatibility mode.
18215                     Uri data = intent.getData();
18216                     String ssp;
18217                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18218                         final boolean replacing =
18219                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18220                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18221
18222                         try {
18223                             ApplicationInfo ai = AppGlobals.getPackageManager().
18224                                     getApplicationInfo(ssp, 0, 0);
18225                             mBatteryStatsService.notePackageInstalled(ssp,
18226                                     ai != null ? ai.versionCode : 0);
18227                         } catch (RemoteException e) {
18228                         }
18229                     }
18230                     break;
18231                 }
18232                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18233                 {
18234                     Uri data = intent.getData();
18235                     String ssp;
18236                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18237                         // Hide the "unsupported display" dialog if necessary.
18238                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18239                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18240                             mUnsupportedDisplaySizeDialog.dismiss();
18241                             mUnsupportedDisplaySizeDialog = null;
18242                         }
18243                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18244                     }
18245                     break;
18246                 }
18247                 case Intent.ACTION_TIMEZONE_CHANGED:
18248                     // If this is the time zone changed action, queue up a message that will reset
18249                     // the timezone of all currently running processes. This message will get
18250                     // queued up before the broadcast happens.
18251                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18252                     break;
18253                 case Intent.ACTION_TIME_CHANGED:
18254                     // If the user set the time, let all running processes know.
18255                     final int is24Hour =
18256                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18257                                     : 0;
18258                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18259                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18260                     synchronized (stats) {
18261                         stats.noteCurrentTimeChangedLocked();
18262                     }
18263                     break;
18264                 case Intent.ACTION_CLEAR_DNS_CACHE:
18265                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18266                     break;
18267                 case Proxy.PROXY_CHANGE_ACTION:
18268                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18269                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18270                     break;
18271                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18272                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18273                     // These broadcasts are no longer allowed by the system, since they can
18274                     // cause significant thrashing at a crictical point (using the camera).
18275                     // Apps should use JobScehduler to monitor for media provider changes.
18276                     Slog.w(TAG, action + " no longer allowed; dropping from "
18277                             + UserHandle.formatUid(callingUid));
18278                     if (resultTo != null) {
18279                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18280                         try {
18281                             queue.performReceiveLocked(callerApp, resultTo, intent,
18282                                     Activity.RESULT_CANCELED, null, null,
18283                                     false, false, userId);
18284                         } catch (RemoteException e) {
18285                             Slog.w(TAG, "Failure ["
18286                                     + queue.mQueueName + "] sending broadcast result of "
18287                                     + intent, e);
18288
18289                         }
18290                     }
18291                     // Lie; we don't want to crash the app.
18292                     return ActivityManager.BROADCAST_SUCCESS;
18293             }
18294         }
18295
18296         // Add to the sticky list if requested.
18297         if (sticky) {
18298             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18299                     callingPid, callingUid)
18300                     != PackageManager.PERMISSION_GRANTED) {
18301                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18302                         + callingPid + ", uid=" + callingUid
18303                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18304                 Slog.w(TAG, msg);
18305                 throw new SecurityException(msg);
18306             }
18307             if (requiredPermissions != null && requiredPermissions.length > 0) {
18308                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18309                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18310                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18311             }
18312             if (intent.getComponent() != null) {
18313                 throw new SecurityException(
18314                         "Sticky broadcasts can't target a specific component");
18315             }
18316             // We use userId directly here, since the "all" target is maintained
18317             // as a separate set of sticky broadcasts.
18318             if (userId != UserHandle.USER_ALL) {
18319                 // But first, if this is not a broadcast to all users, then
18320                 // make sure it doesn't conflict with an existing broadcast to
18321                 // all users.
18322                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18323                         UserHandle.USER_ALL);
18324                 if (stickies != null) {
18325                     ArrayList<Intent> list = stickies.get(intent.getAction());
18326                     if (list != null) {
18327                         int N = list.size();
18328                         int i;
18329                         for (i=0; i<N; i++) {
18330                             if (intent.filterEquals(list.get(i))) {
18331                                 throw new IllegalArgumentException(
18332                                         "Sticky broadcast " + intent + " for user "
18333                                         + userId + " conflicts with existing global broadcast");
18334                             }
18335                         }
18336                     }
18337                 }
18338             }
18339             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18340             if (stickies == null) {
18341                 stickies = new ArrayMap<>();
18342                 mStickyBroadcasts.put(userId, stickies);
18343             }
18344             ArrayList<Intent> list = stickies.get(intent.getAction());
18345             if (list == null) {
18346                 list = new ArrayList<>();
18347                 stickies.put(intent.getAction(), list);
18348             }
18349             final int stickiesCount = list.size();
18350             int i;
18351             for (i = 0; i < stickiesCount; i++) {
18352                 if (intent.filterEquals(list.get(i))) {
18353                     // This sticky already exists, replace it.
18354                     list.set(i, new Intent(intent));
18355                     break;
18356                 }
18357             }
18358             if (i >= stickiesCount) {
18359                 list.add(new Intent(intent));
18360             }
18361         }
18362
18363         int[] users;
18364         if (userId == UserHandle.USER_ALL) {
18365             // Caller wants broadcast to go to all started users.
18366             users = mUserController.getStartedUserArrayLocked();
18367         } else {
18368             // Caller wants broadcast to go to one specific user.
18369             users = new int[] {userId};
18370         }
18371
18372         // Figure out who all will receive this broadcast.
18373         List receivers = null;
18374         List<BroadcastFilter> registeredReceivers = null;
18375         // Need to resolve the intent to interested receivers...
18376         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18377                  == 0) {
18378             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18379         }
18380         if (intent.getComponent() == null) {
18381             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18382                 // Query one target user at a time, excluding shell-restricted users
18383                 for (int i = 0; i < users.length; i++) {
18384                     if (mUserController.hasUserRestriction(
18385                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18386                         continue;
18387                     }
18388                     List<BroadcastFilter> registeredReceiversForUser =
18389                             mReceiverResolver.queryIntent(intent,
18390                                     resolvedType, false, users[i]);
18391                     if (registeredReceivers == null) {
18392                         registeredReceivers = registeredReceiversForUser;
18393                     } else if (registeredReceiversForUser != null) {
18394                         registeredReceivers.addAll(registeredReceiversForUser);
18395                     }
18396                 }
18397             } else {
18398                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18399                         resolvedType, false, userId);
18400             }
18401         }
18402
18403         final boolean replacePending =
18404                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18405
18406         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18407                 + " replacePending=" + replacePending);
18408
18409         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18410         if (!ordered && NR > 0) {
18411             // If we are not serializing this broadcast, then send the
18412             // registered receivers separately so they don't wait for the
18413             // components to be launched.
18414             if (isCallerSystem) {
18415                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18416                         isProtectedBroadcast, registeredReceivers);
18417             }
18418             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18419             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18420                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18421                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18422                     resultExtras, ordered, sticky, false, userId);
18423             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18424             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18425             if (!replaced) {
18426                 queue.enqueueParallelBroadcastLocked(r);
18427                 queue.scheduleBroadcastsLocked();
18428             }
18429             registeredReceivers = null;
18430             NR = 0;
18431         }
18432
18433         // Merge into one list.
18434         int ir = 0;
18435         if (receivers != null) {
18436             // A special case for PACKAGE_ADDED: do not allow the package
18437             // being added to see this broadcast.  This prevents them from
18438             // using this as a back door to get run as soon as they are
18439             // installed.  Maybe in the future we want to have a special install
18440             // broadcast or such for apps, but we'd like to deliberately make
18441             // this decision.
18442             String skipPackages[] = null;
18443             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18444                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18445                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18446                 Uri data = intent.getData();
18447                 if (data != null) {
18448                     String pkgName = data.getSchemeSpecificPart();
18449                     if (pkgName != null) {
18450                         skipPackages = new String[] { pkgName };
18451                     }
18452                 }
18453             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18454                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18455             }
18456             if (skipPackages != null && (skipPackages.length > 0)) {
18457                 for (String skipPackage : skipPackages) {
18458                     if (skipPackage != null) {
18459                         int NT = receivers.size();
18460                         for (int it=0; it<NT; it++) {
18461                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18462                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18463                                 receivers.remove(it);
18464                                 it--;
18465                                 NT--;
18466                             }
18467                         }
18468                     }
18469                 }
18470             }
18471
18472             int NT = receivers != null ? receivers.size() : 0;
18473             int it = 0;
18474             ResolveInfo curt = null;
18475             BroadcastFilter curr = null;
18476             while (it < NT && ir < NR) {
18477                 if (curt == null) {
18478                     curt = (ResolveInfo)receivers.get(it);
18479                 }
18480                 if (curr == null) {
18481                     curr = registeredReceivers.get(ir);
18482                 }
18483                 if (curr.getPriority() >= curt.priority) {
18484                     // Insert this broadcast record into the final list.
18485                     receivers.add(it, curr);
18486                     ir++;
18487                     curr = null;
18488                     it++;
18489                     NT++;
18490                 } else {
18491                     // Skip to the next ResolveInfo in the final list.
18492                     it++;
18493                     curt = null;
18494                 }
18495             }
18496         }
18497         while (ir < NR) {
18498             if (receivers == null) {
18499                 receivers = new ArrayList();
18500             }
18501             receivers.add(registeredReceivers.get(ir));
18502             ir++;
18503         }
18504
18505         if (isCallerSystem) {
18506             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18507                     isProtectedBroadcast, receivers);
18508         }
18509
18510         if ((receivers != null && receivers.size() > 0)
18511                 || resultTo != null) {
18512             BroadcastQueue queue = broadcastQueueForIntent(intent);
18513             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18514                     callerPackage, callingPid, callingUid, resolvedType,
18515                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18516                     resultData, resultExtras, ordered, sticky, false, userId);
18517
18518             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18519                     + ": prev had " + queue.mOrderedBroadcasts.size());
18520             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18521                     "Enqueueing broadcast " + r.intent.getAction());
18522
18523             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18524             if (!replaced) {
18525                 queue.enqueueOrderedBroadcastLocked(r);
18526                 queue.scheduleBroadcastsLocked();
18527             }
18528         } else {
18529             // There was nobody interested in the broadcast, but we still want to record
18530             // that it happened.
18531             if (intent.getComponent() == null && intent.getPackage() == null
18532                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18533                 // This was an implicit broadcast... let's record it for posterity.
18534                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18535             }
18536         }
18537
18538         return ActivityManager.BROADCAST_SUCCESS;
18539     }
18540
18541     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18542             int skipCount, long dispatchTime) {
18543         final long now = SystemClock.elapsedRealtime();
18544         if (mCurBroadcastStats == null ||
18545                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18546             mLastBroadcastStats = mCurBroadcastStats;
18547             if (mLastBroadcastStats != null) {
18548                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18549                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18550             }
18551             mCurBroadcastStats = new BroadcastStats();
18552         }
18553         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18554     }
18555
18556     final Intent verifyBroadcastLocked(Intent intent) {
18557         // Refuse possible leaked file descriptors
18558         if (intent != null && intent.hasFileDescriptors() == true) {
18559             throw new IllegalArgumentException("File descriptors passed in Intent");
18560         }
18561
18562         int flags = intent.getFlags();
18563
18564         if (!mProcessesReady) {
18565             // if the caller really truly claims to know what they're doing, go
18566             // ahead and allow the broadcast without launching any receivers
18567             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18568                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18569             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18570                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18571                         + " before boot completion");
18572                 throw new IllegalStateException("Cannot broadcast before boot completed");
18573             }
18574         }
18575
18576         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18577             throw new IllegalArgumentException(
18578                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18579         }
18580
18581         return intent;
18582     }
18583
18584     public final int broadcastIntent(IApplicationThread caller,
18585             Intent intent, String resolvedType, IIntentReceiver resultTo,
18586             int resultCode, String resultData, Bundle resultExtras,
18587             String[] requiredPermissions, int appOp, Bundle bOptions,
18588             boolean serialized, boolean sticky, int userId) {
18589         enforceNotIsolatedCaller("broadcastIntent");
18590         synchronized(this) {
18591             intent = verifyBroadcastLocked(intent);
18592
18593             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18594             final int callingPid = Binder.getCallingPid();
18595             final int callingUid = Binder.getCallingUid();
18596             final long origId = Binder.clearCallingIdentity();
18597             int res = broadcastIntentLocked(callerApp,
18598                     callerApp != null ? callerApp.info.packageName : null,
18599                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18600                     requiredPermissions, appOp, bOptions, serialized, sticky,
18601                     callingPid, callingUid, userId);
18602             Binder.restoreCallingIdentity(origId);
18603             return res;
18604         }
18605     }
18606
18607
18608     int broadcastIntentInPackage(String packageName, int uid,
18609             Intent intent, String resolvedType, IIntentReceiver resultTo,
18610             int resultCode, String resultData, Bundle resultExtras,
18611             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18612             int userId) {
18613         synchronized(this) {
18614             intent = verifyBroadcastLocked(intent);
18615
18616             final long origId = Binder.clearCallingIdentity();
18617             String[] requiredPermissions = requiredPermission == null ? null
18618                     : new String[] {requiredPermission};
18619             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18620                     resultTo, resultCode, resultData, resultExtras,
18621                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18622                     sticky, -1, uid, userId);
18623             Binder.restoreCallingIdentity(origId);
18624             return res;
18625         }
18626     }
18627
18628     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18629         // Refuse possible leaked file descriptors
18630         if (intent != null && intent.hasFileDescriptors() == true) {
18631             throw new IllegalArgumentException("File descriptors passed in Intent");
18632         }
18633
18634         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18635                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18636
18637         synchronized(this) {
18638             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18639                     != PackageManager.PERMISSION_GRANTED) {
18640                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18641                         + Binder.getCallingPid()
18642                         + ", uid=" + Binder.getCallingUid()
18643                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18644                 Slog.w(TAG, msg);
18645                 throw new SecurityException(msg);
18646             }
18647             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18648             if (stickies != null) {
18649                 ArrayList<Intent> list = stickies.get(intent.getAction());
18650                 if (list != null) {
18651                     int N = list.size();
18652                     int i;
18653                     for (i=0; i<N; i++) {
18654                         if (intent.filterEquals(list.get(i))) {
18655                             list.remove(i);
18656                             break;
18657                         }
18658                     }
18659                     if (list.size() <= 0) {
18660                         stickies.remove(intent.getAction());
18661                     }
18662                 }
18663                 if (stickies.size() <= 0) {
18664                     mStickyBroadcasts.remove(userId);
18665                 }
18666             }
18667         }
18668     }
18669
18670     void backgroundServicesFinishedLocked(int userId) {
18671         for (BroadcastQueue queue : mBroadcastQueues) {
18672             queue.backgroundServicesFinishedLocked(userId);
18673         }
18674     }
18675
18676     public void finishReceiver(IBinder who, int resultCode, String resultData,
18677             Bundle resultExtras, boolean resultAbort, int flags) {
18678         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18679
18680         // Refuse possible leaked file descriptors
18681         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18682             throw new IllegalArgumentException("File descriptors passed in Bundle");
18683         }
18684
18685         final long origId = Binder.clearCallingIdentity();
18686         try {
18687             boolean doNext = false;
18688             BroadcastRecord r;
18689
18690             synchronized(this) {
18691                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18692                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18693                 r = queue.getMatchingOrderedReceiver(who);
18694                 if (r != null) {
18695                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18696                         resultData, resultExtras, resultAbort, true);
18697                 }
18698             }
18699
18700             if (doNext) {
18701                 r.queue.processNextBroadcast(false);
18702             }
18703             trimApplications();
18704         } finally {
18705             Binder.restoreCallingIdentity(origId);
18706         }
18707     }
18708
18709     // =========================================================
18710     // INSTRUMENTATION
18711     // =========================================================
18712
18713     public boolean startInstrumentation(ComponentName className,
18714             String profileFile, int flags, Bundle arguments,
18715             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18716             int userId, String abiOverride) {
18717         enforceNotIsolatedCaller("startInstrumentation");
18718         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18719                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18720         // Refuse possible leaked file descriptors
18721         if (arguments != null && arguments.hasFileDescriptors()) {
18722             throw new IllegalArgumentException("File descriptors passed in Bundle");
18723         }
18724
18725         synchronized(this) {
18726             InstrumentationInfo ii = null;
18727             ApplicationInfo ai = null;
18728             try {
18729                 ii = mContext.getPackageManager().getInstrumentationInfo(
18730                     className, STOCK_PM_FLAGS);
18731                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18732                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18733             } catch (PackageManager.NameNotFoundException e) {
18734             } catch (RemoteException e) {
18735             }
18736             if (ii == null) {
18737                 reportStartInstrumentationFailureLocked(watcher, className,
18738                         "Unable to find instrumentation info for: " + className);
18739                 return false;
18740             }
18741             if (ai == null) {
18742                 reportStartInstrumentationFailureLocked(watcher, className,
18743                         "Unable to find instrumentation target package: " + ii.targetPackage);
18744                 return false;
18745             }
18746             if (!ai.hasCode()) {
18747                 reportStartInstrumentationFailureLocked(watcher, className,
18748                         "Instrumentation target has no code: " + ii.targetPackage);
18749                 return false;
18750             }
18751
18752             int match = mContext.getPackageManager().checkSignatures(
18753                     ii.targetPackage, ii.packageName);
18754             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18755                 String msg = "Permission Denial: starting instrumentation "
18756                         + className + " from pid="
18757                         + Binder.getCallingPid()
18758                         + ", uid=" + Binder.getCallingPid()
18759                         + " not allowed because package " + ii.packageName
18760                         + " does not have a signature matching the target "
18761                         + ii.targetPackage;
18762                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18763                 throw new SecurityException(msg);
18764             }
18765
18766             final long origId = Binder.clearCallingIdentity();
18767             // Instrumentation can kill and relaunch even persistent processes
18768             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18769                     "start instr");
18770             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18771             app.instrumentationClass = className;
18772             app.instrumentationInfo = ai;
18773             app.instrumentationProfileFile = profileFile;
18774             app.instrumentationArguments = arguments;
18775             app.instrumentationWatcher = watcher;
18776             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18777             app.instrumentationResultClass = className;
18778             Binder.restoreCallingIdentity(origId);
18779         }
18780
18781         return true;
18782     }
18783
18784     /**
18785      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18786      * error to the logs, but if somebody is watching, send the report there too.  This enables
18787      * the "am" command to report errors with more information.
18788      *
18789      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18790      * @param cn The component name of the instrumentation.
18791      * @param report The error report.
18792      */
18793     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18794             ComponentName cn, String report) {
18795         Slog.w(TAG, report);
18796         if (watcher != null) {
18797             Bundle results = new Bundle();
18798             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18799             results.putString("Error", report);
18800             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18801         }
18802     }
18803
18804     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18805         if (app.instrumentationWatcher != null) {
18806             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18807                     app.instrumentationClass, resultCode, results);
18808         }
18809
18810         // Can't call out of the system process with a lock held, so post a message.
18811         if (app.instrumentationUiAutomationConnection != null) {
18812             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18813                     app.instrumentationUiAutomationConnection).sendToTarget();
18814         }
18815
18816         app.instrumentationWatcher = null;
18817         app.instrumentationUiAutomationConnection = null;
18818         app.instrumentationClass = null;
18819         app.instrumentationInfo = null;
18820         app.instrumentationProfileFile = null;
18821         app.instrumentationArguments = null;
18822
18823         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18824                 "finished inst");
18825     }
18826
18827     public void finishInstrumentation(IApplicationThread target,
18828             int resultCode, Bundle results) {
18829         int userId = UserHandle.getCallingUserId();
18830         // Refuse possible leaked file descriptors
18831         if (results != null && results.hasFileDescriptors()) {
18832             throw new IllegalArgumentException("File descriptors passed in Intent");
18833         }
18834
18835         synchronized(this) {
18836             ProcessRecord app = getRecordForAppLocked(target);
18837             if (app == null) {
18838                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18839                 return;
18840             }
18841             final long origId = Binder.clearCallingIdentity();
18842             finishInstrumentationLocked(app, resultCode, results);
18843             Binder.restoreCallingIdentity(origId);
18844         }
18845     }
18846
18847     // =========================================================
18848     // CONFIGURATION
18849     // =========================================================
18850
18851     public ConfigurationInfo getDeviceConfigurationInfo() {
18852         ConfigurationInfo config = new ConfigurationInfo();
18853         synchronized (this) {
18854             config.reqTouchScreen = mConfiguration.touchscreen;
18855             config.reqKeyboardType = mConfiguration.keyboard;
18856             config.reqNavigation = mConfiguration.navigation;
18857             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18858                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18859                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18860             }
18861             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18862                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18863                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18864             }
18865             config.reqGlEsVersion = GL_ES_VERSION;
18866         }
18867         return config;
18868     }
18869
18870     ActivityStack getFocusedStack() {
18871         return mStackSupervisor.getFocusedStack();
18872     }
18873
18874     @Override
18875     public int getFocusedStackId() throws RemoteException {
18876         ActivityStack focusedStack = getFocusedStack();
18877         if (focusedStack != null) {
18878             return focusedStack.getStackId();
18879         }
18880         return -1;
18881     }
18882
18883     public Configuration getConfiguration() {
18884         Configuration ci;
18885         synchronized(this) {
18886             ci = new Configuration(mConfiguration);
18887             ci.userSetLocale = false;
18888         }
18889         return ci;
18890     }
18891
18892     @Override
18893     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18894         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18895         synchronized (this) {
18896             mSuppressResizeConfigChanges = suppress;
18897         }
18898     }
18899
18900     @Override
18901     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18902         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18903         if (fromStackId == HOME_STACK_ID) {
18904             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18905         }
18906         synchronized (this) {
18907             final long origId = Binder.clearCallingIdentity();
18908             try {
18909                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18910             } finally {
18911                 Binder.restoreCallingIdentity(origId);
18912             }
18913         }
18914     }
18915
18916     @Override
18917     public void updatePersistentConfiguration(Configuration values) {
18918         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18919                 "updateConfiguration()");
18920         enforceWriteSettingsPermission("updateConfiguration()");
18921         if (values == null) {
18922             throw new NullPointerException("Configuration must not be null");
18923         }
18924
18925         int userId = UserHandle.getCallingUserId();
18926
18927         synchronized(this) {
18928             updatePersistentConfigurationLocked(values, userId);
18929         }
18930     }
18931
18932     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18933         final long origId = Binder.clearCallingIdentity();
18934         try {
18935             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18936         } finally {
18937             Binder.restoreCallingIdentity(origId);
18938         }
18939     }
18940
18941     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18942         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18943                 FONT_SCALE, 1.0f, userId);
18944         if (mConfiguration.fontScale != scaleFactor) {
18945             final Configuration configuration = mWindowManager.computeNewConfiguration();
18946             configuration.fontScale = scaleFactor;
18947             synchronized (this) {
18948                 updatePersistentConfigurationLocked(configuration, userId);
18949             }
18950         }
18951     }
18952
18953     private void enforceWriteSettingsPermission(String func) {
18954         int uid = Binder.getCallingUid();
18955         if (uid == Process.ROOT_UID) {
18956             return;
18957         }
18958
18959         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18960                 Settings.getPackageNameForUid(mContext, uid), false)) {
18961             return;
18962         }
18963
18964         String msg = "Permission Denial: " + func + " from pid="
18965                 + Binder.getCallingPid()
18966                 + ", uid=" + uid
18967                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18968         Slog.w(TAG, msg);
18969         throw new SecurityException(msg);
18970     }
18971
18972     public void updateConfiguration(Configuration values) {
18973         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18974                 "updateConfiguration()");
18975
18976         synchronized(this) {
18977             if (values == null && mWindowManager != null) {
18978                 // sentinel: fetch the current configuration from the window manager
18979                 values = mWindowManager.computeNewConfiguration();
18980             }
18981
18982             if (mWindowManager != null) {
18983                 mProcessList.applyDisplaySize(mWindowManager);
18984             }
18985
18986             final long origId = Binder.clearCallingIdentity();
18987             if (values != null) {
18988                 Settings.System.clearConfiguration(values);
18989             }
18990             updateConfigurationLocked(values, null, false);
18991             Binder.restoreCallingIdentity(origId);
18992         }
18993     }
18994
18995     void updateUserConfigurationLocked() {
18996         Configuration configuration = new Configuration(mConfiguration);
18997         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18998                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18999         updateConfigurationLocked(configuration, null, false);
19000     }
19001
19002     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19003             boolean initLocale) {
19004         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19005     }
19006
19007     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19008             boolean initLocale, boolean deferResume) {
19009         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19010         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19011                 UserHandle.USER_NULL, deferResume);
19012     }
19013
19014     // To cache the list of supported system locales
19015     private String[] mSupportedSystemLocales = null;
19016
19017     /**
19018      * Do either or both things: (1) change the current configuration, and (2)
19019      * make sure the given activity is running with the (now) current
19020      * configuration.  Returns true if the activity has been left running, or
19021      * false if <var>starting</var> is being destroyed to match the new
19022      * configuration.
19023      *
19024      * @param userId is only used when persistent parameter is set to true to persist configuration
19025      *               for that particular user
19026      */
19027     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19028             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19029         int changes = 0;
19030
19031         if (mWindowManager != null) {
19032             mWindowManager.deferSurfaceLayout();
19033         }
19034         if (values != null) {
19035             Configuration newConfig = new Configuration(mConfiguration);
19036             changes = newConfig.updateFrom(values);
19037             if (changes != 0) {
19038                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19039                         "Updating configuration to: " + values);
19040
19041                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19042
19043                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19044                     final LocaleList locales = values.getLocales();
19045                     int bestLocaleIndex = 0;
19046                     if (locales.size() > 1) {
19047                         if (mSupportedSystemLocales == null) {
19048                             mSupportedSystemLocales =
19049                                     Resources.getSystem().getAssets().getLocales();
19050                         }
19051                         bestLocaleIndex = Math.max(0,
19052                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
19053                     }
19054                     SystemProperties.set("persist.sys.locale",
19055                             locales.get(bestLocaleIndex).toLanguageTag());
19056                     LocaleList.setDefault(locales, bestLocaleIndex);
19057                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19058                             locales.get(bestLocaleIndex)));
19059                 }
19060
19061                 mConfigurationSeq++;
19062                 if (mConfigurationSeq <= 0) {
19063                     mConfigurationSeq = 1;
19064                 }
19065                 newConfig.seq = mConfigurationSeq;
19066                 mConfiguration = newConfig;
19067                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19068                 mUsageStatsService.reportConfigurationChange(newConfig,
19069                         mUserController.getCurrentUserIdLocked());
19070                 //mUsageStatsService.noteStartConfig(newConfig);
19071
19072                 final Configuration configCopy = new Configuration(mConfiguration);
19073
19074                 // TODO: If our config changes, should we auto dismiss any currently
19075                 // showing dialogs?
19076                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19077
19078                 AttributeCache ac = AttributeCache.instance();
19079                 if (ac != null) {
19080                     ac.updateConfiguration(configCopy);
19081                 }
19082
19083                 // Make sure all resources in our process are updated
19084                 // right now, so that anyone who is going to retrieve
19085                 // resource values after we return will be sure to get
19086                 // the new ones.  This is especially important during
19087                 // boot, where the first config change needs to guarantee
19088                 // all resources have that config before following boot
19089                 // code is executed.
19090                 mSystemThread.applyConfigurationToResources(configCopy);
19091
19092                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19093                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19094                     msg.obj = new Configuration(configCopy);
19095                     msg.arg1 = userId;
19096                     mHandler.sendMessage(msg);
19097                 }
19098
19099                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19100                 if (isDensityChange) {
19101                     // Reset the unsupported display size dialog.
19102                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19103
19104                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19105                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19106                 }
19107
19108                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19109                     ProcessRecord app = mLruProcesses.get(i);
19110                     try {
19111                         if (app.thread != null) {
19112                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19113                                     + app.processName + " new config " + mConfiguration);
19114                             app.thread.scheduleConfigurationChanged(configCopy);
19115                         }
19116                     } catch (Exception e) {
19117                     }
19118                 }
19119                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19120                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19121                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19122                         | Intent.FLAG_RECEIVER_FOREGROUND);
19123                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19124                         null, AppOpsManager.OP_NONE, null, false, false,
19125                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19126                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19127                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19128                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19129                     if (initLocale || !mProcessesReady) {
19130                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19131                     }
19132                     broadcastIntentLocked(null, null, intent,
19133                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19134                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19135                 }
19136             }
19137             // Update the configuration with WM first and check if any of the stacks need to be
19138             // resized due to the configuration change. If so, resize the stacks now and do any
19139             // relaunches if necessary. This way we don't need to relaunch again below in
19140             // ensureActivityConfigurationLocked().
19141             if (mWindowManager != null) {
19142                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19143                 if (resizedStacks != null) {
19144                     for (int stackId : resizedStacks) {
19145                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19146                         mStackSupervisor.resizeStackLocked(
19147                                 stackId, newBounds, null, null, false, false, deferResume);
19148                     }
19149                 }
19150             }
19151         }
19152
19153         boolean kept = true;
19154         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19155         // mainStack is null during startup.
19156         if (mainStack != null) {
19157             if (changes != 0 && starting == null) {
19158                 // If the configuration changed, and the caller is not already
19159                 // in the process of starting an activity, then find the top
19160                 // activity to check if its configuration needs to change.
19161                 starting = mainStack.topRunningActivityLocked();
19162             }
19163
19164             if (starting != null) {
19165                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19166                 // And we need to make sure at this point that all other activities
19167                 // are made visible with the correct configuration.
19168                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19169                         !PRESERVE_WINDOWS);
19170             }
19171         }
19172         if (mWindowManager != null) {
19173             mWindowManager.continueSurfaceLayout();
19174         }
19175         return kept;
19176     }
19177
19178     /**
19179      * Decide based on the configuration whether we should shouw the ANR,
19180      * crash, etc dialogs.  The idea is that if there is no affordence to
19181      * press the on-screen buttons, or the user experience would be more
19182      * greatly impacted than the crash itself, we shouldn't show the dialog.
19183      *
19184      * A thought: SystemUI might also want to get told about this, the Power
19185      * dialog / global actions also might want different behaviors.
19186      */
19187     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19188         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19189                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19190                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19191         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19192         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19193                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19194         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19195     }
19196
19197     @Override
19198     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19199         synchronized (this) {
19200             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19201             if (srec != null) {
19202                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19203             }
19204         }
19205         return false;
19206     }
19207
19208     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19209             Intent resultData) {
19210
19211         synchronized (this) {
19212             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19213             if (r != null) {
19214                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19215             }
19216             return false;
19217         }
19218     }
19219
19220     public int getLaunchedFromUid(IBinder activityToken) {
19221         ActivityRecord srec;
19222         synchronized (this) {
19223             srec = ActivityRecord.forTokenLocked(activityToken);
19224         }
19225         if (srec == null) {
19226             return -1;
19227         }
19228         return srec.launchedFromUid;
19229     }
19230
19231     public String getLaunchedFromPackage(IBinder activityToken) {
19232         ActivityRecord srec;
19233         synchronized (this) {
19234             srec = ActivityRecord.forTokenLocked(activityToken);
19235         }
19236         if (srec == null) {
19237             return null;
19238         }
19239         return srec.launchedFromPackage;
19240     }
19241
19242     // =========================================================
19243     // LIFETIME MANAGEMENT
19244     // =========================================================
19245
19246     // Returns which broadcast queue the app is the current [or imminent] receiver
19247     // on, or 'null' if the app is not an active broadcast recipient.
19248     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19249         BroadcastRecord r = app.curReceiver;
19250         if (r != null) {
19251             return r.queue;
19252         }
19253
19254         // It's not the current receiver, but it might be starting up to become one
19255         synchronized (this) {
19256             for (BroadcastQueue queue : mBroadcastQueues) {
19257                 r = queue.mPendingBroadcast;
19258                 if (r != null && r.curApp == app) {
19259                     // found it; report which queue it's in
19260                     return queue;
19261                 }
19262             }
19263         }
19264
19265         return null;
19266     }
19267
19268     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19269             int targetUid, ComponentName targetComponent, String targetProcess) {
19270         if (!mTrackingAssociations) {
19271             return null;
19272         }
19273         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19274                 = mAssociations.get(targetUid);
19275         if (components == null) {
19276             components = new ArrayMap<>();
19277             mAssociations.put(targetUid, components);
19278         }
19279         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19280         if (sourceUids == null) {
19281             sourceUids = new SparseArray<>();
19282             components.put(targetComponent, sourceUids);
19283         }
19284         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19285         if (sourceProcesses == null) {
19286             sourceProcesses = new ArrayMap<>();
19287             sourceUids.put(sourceUid, sourceProcesses);
19288         }
19289         Association ass = sourceProcesses.get(sourceProcess);
19290         if (ass == null) {
19291             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19292                     targetProcess);
19293             sourceProcesses.put(sourceProcess, ass);
19294         }
19295         ass.mCount++;
19296         ass.mNesting++;
19297         if (ass.mNesting == 1) {
19298             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19299             ass.mLastState = sourceState;
19300         }
19301         return ass;
19302     }
19303
19304     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19305             ComponentName targetComponent) {
19306         if (!mTrackingAssociations) {
19307             return;
19308         }
19309         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19310                 = mAssociations.get(targetUid);
19311         if (components == null) {
19312             return;
19313         }
19314         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19315         if (sourceUids == null) {
19316             return;
19317         }
19318         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19319         if (sourceProcesses == null) {
19320             return;
19321         }
19322         Association ass = sourceProcesses.get(sourceProcess);
19323         if (ass == null || ass.mNesting <= 0) {
19324             return;
19325         }
19326         ass.mNesting--;
19327         if (ass.mNesting == 0) {
19328             long uptime = SystemClock.uptimeMillis();
19329             ass.mTime += uptime - ass.mStartTime;
19330             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19331                     += uptime - ass.mLastStateUptime;
19332             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19333         }
19334     }
19335
19336     private void noteUidProcessState(final int uid, final int state) {
19337         mBatteryStatsService.noteUidProcessState(uid, state);
19338         if (mTrackingAssociations) {
19339             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19340                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19341                         = mAssociations.valueAt(i1);
19342                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19343                     SparseArray<ArrayMap<String, Association>> sourceUids
19344                             = targetComponents.valueAt(i2);
19345                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19346                     if (sourceProcesses != null) {
19347                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19348                             Association ass = sourceProcesses.valueAt(i4);
19349                             if (ass.mNesting >= 1) {
19350                                 // currently associated
19351                                 long uptime = SystemClock.uptimeMillis();
19352                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19353                                         += uptime - ass.mLastStateUptime;
19354                                 ass.mLastState = state;
19355                                 ass.mLastStateUptime = uptime;
19356                             }
19357                         }
19358                     }
19359                 }
19360             }
19361         }
19362     }
19363
19364     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19365             boolean doingAll, long now) {
19366         if (mAdjSeq == app.adjSeq) {
19367             // This adjustment has already been computed.
19368             return app.curRawAdj;
19369         }
19370
19371         if (app.thread == null) {
19372             app.adjSeq = mAdjSeq;
19373             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19374             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19375             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19376         }
19377
19378         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19379         app.adjSource = null;
19380         app.adjTarget = null;
19381         app.empty = false;
19382         app.cached = false;
19383
19384         final int activitiesSize = app.activities.size();
19385
19386         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19387             // The max adjustment doesn't allow this app to be anything
19388             // below foreground, so it is not worth doing work for it.
19389             app.adjType = "fixed";
19390             app.adjSeq = mAdjSeq;
19391             app.curRawAdj = app.maxAdj;
19392             app.foregroundActivities = false;
19393             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19394             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19395             // System processes can do UI, and when they do we want to have
19396             // them trim their memory after the user leaves the UI.  To
19397             // facilitate this, here we need to determine whether or not it
19398             // is currently showing UI.
19399             app.systemNoUi = true;
19400             if (app == TOP_APP) {
19401                 app.systemNoUi = false;
19402                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19403                 app.adjType = "pers-top-activity";
19404             } else if (app.hasTopUi) {
19405                 app.systemNoUi = false;
19406                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19407                 app.adjType = "pers-top-ui";
19408             } else if (activitiesSize > 0) {
19409                 for (int j = 0; j < activitiesSize; j++) {
19410                     final ActivityRecord r = app.activities.get(j);
19411                     if (r.visible) {
19412                         app.systemNoUi = false;
19413                     }
19414                 }
19415             }
19416             if (!app.systemNoUi) {
19417                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19418             }
19419             return (app.curAdj=app.maxAdj);
19420         }
19421
19422         app.systemNoUi = false;
19423
19424         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19425
19426         // Determine the importance of the process, starting with most
19427         // important to least, and assign an appropriate OOM adjustment.
19428         int adj;
19429         int schedGroup;
19430         int procState;
19431         boolean foregroundActivities = false;
19432         BroadcastQueue queue;
19433         if (app == TOP_APP) {
19434             // The last app on the list is the foreground app.
19435             adj = ProcessList.FOREGROUND_APP_ADJ;
19436             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19437             app.adjType = "top-activity";
19438             foregroundActivities = true;
19439             procState = PROCESS_STATE_CUR_TOP;
19440         } else if (app.instrumentationClass != null) {
19441             // Don't want to kill running instrumentation.
19442             adj = ProcessList.FOREGROUND_APP_ADJ;
19443             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19444             app.adjType = "instrumentation";
19445             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19446         } else if ((queue = isReceivingBroadcast(app)) != null) {
19447             // An app that is currently receiving a broadcast also
19448             // counts as being in the foreground for OOM killer purposes.
19449             // It's placed in a sched group based on the nature of the
19450             // broadcast as reflected by which queue it's active in.
19451             adj = ProcessList.FOREGROUND_APP_ADJ;
19452             schedGroup = (queue == mFgBroadcastQueue)
19453                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19454             app.adjType = "broadcast";
19455             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19456         } else if (app.executingServices.size() > 0) {
19457             // An app that is currently executing a service callback also
19458             // counts as being in the foreground.
19459             adj = ProcessList.FOREGROUND_APP_ADJ;
19460             schedGroup = app.execServicesFg ?
19461                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19462             app.adjType = "exec-service";
19463             procState = ActivityManager.PROCESS_STATE_SERVICE;
19464             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19465         } else {
19466             // As far as we know the process is empty.  We may change our mind later.
19467             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19468             // At this point we don't actually know the adjustment.  Use the cached adj
19469             // value that the caller wants us to.
19470             adj = cachedAdj;
19471             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19472             app.cached = true;
19473             app.empty = true;
19474             app.adjType = "cch-empty";
19475         }
19476
19477         // Examine all activities if not already foreground.
19478         if (!foregroundActivities && activitiesSize > 0) {
19479             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19480             for (int j = 0; j < activitiesSize; j++) {
19481                 final ActivityRecord r = app.activities.get(j);
19482                 if (r.app != app) {
19483                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19484                             + " instead of expected " + app);
19485                     if (r.app == null || (r.app.uid == app.uid)) {
19486                         // Only fix things up when they look sane
19487                         r.app = app;
19488                     } else {
19489                         continue;
19490                     }
19491                 }
19492                 if (r.visible) {
19493                     // App has a visible activity; only upgrade adjustment.
19494                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19495                         adj = ProcessList.VISIBLE_APP_ADJ;
19496                         app.adjType = "visible";
19497                     }
19498                     if (procState > PROCESS_STATE_CUR_TOP) {
19499                         procState = PROCESS_STATE_CUR_TOP;
19500                     }
19501                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19502                     app.cached = false;
19503                     app.empty = false;
19504                     foregroundActivities = true;
19505                     if (r.task != null && minLayer > 0) {
19506                         final int layer = r.task.mLayerRank;
19507                         if (layer >= 0 && minLayer > layer) {
19508                             minLayer = layer;
19509                         }
19510                     }
19511                     break;
19512                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19513                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19514                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19515                         app.adjType = "pausing";
19516                     }
19517                     if (procState > PROCESS_STATE_CUR_TOP) {
19518                         procState = PROCESS_STATE_CUR_TOP;
19519                     }
19520                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19521                     app.cached = false;
19522                     app.empty = false;
19523                     foregroundActivities = true;
19524                 } else if (r.state == ActivityState.STOPPING) {
19525                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19526                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19527                         app.adjType = "stopping";
19528                     }
19529                     // For the process state, we will at this point consider the
19530                     // process to be cached.  It will be cached either as an activity
19531                     // or empty depending on whether the activity is finishing.  We do
19532                     // this so that we can treat the process as cached for purposes of
19533                     // memory trimming (determing current memory level, trim command to
19534                     // send to process) since there can be an arbitrary number of stopping
19535                     // processes and they should soon all go into the cached state.
19536                     if (!r.finishing) {
19537                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19538                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19539                         }
19540                     }
19541                     app.cached = false;
19542                     app.empty = false;
19543                     foregroundActivities = true;
19544                 } else {
19545                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19546                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19547                         app.adjType = "cch-act";
19548                     }
19549                 }
19550             }
19551             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19552                 adj += minLayer;
19553             }
19554         }
19555
19556         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19557                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19558             if (app.foregroundServices) {
19559                 // The user is aware of this app, so make it visible.
19560                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19561                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19562                 app.cached = false;
19563                 app.adjType = "fg-service";
19564                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19565             } else if (app.forcingToForeground != null) {
19566                 // The user is aware of this app, so make it visible.
19567                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19568                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19569                 app.cached = false;
19570                 app.adjType = "force-fg";
19571                 app.adjSource = app.forcingToForeground;
19572                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19573             }
19574         }
19575
19576         if (app == mHeavyWeightProcess) {
19577             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19578                 // We don't want to kill the current heavy-weight process.
19579                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19580                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19581                 app.cached = false;
19582                 app.adjType = "heavy";
19583             }
19584             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19585                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19586             }
19587         }
19588
19589         if (app == mHomeProcess) {
19590             if (adj > ProcessList.HOME_APP_ADJ) {
19591                 // This process is hosting what we currently consider to be the
19592                 // home app, so we don't want to let it go into the background.
19593                 adj = ProcessList.HOME_APP_ADJ;
19594                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19595                 app.cached = false;
19596                 app.adjType = "home";
19597             }
19598             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19599                 procState = ActivityManager.PROCESS_STATE_HOME;
19600             }
19601         }
19602
19603         if (app == mPreviousProcess && app.activities.size() > 0) {
19604             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19605                 // This was the previous process that showed UI to the user.
19606                 // We want to try to keep it around more aggressively, to give
19607                 // a good experience around switching between two apps.
19608                 adj = ProcessList.PREVIOUS_APP_ADJ;
19609                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19610                 app.cached = false;
19611                 app.adjType = "previous";
19612             }
19613             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19614                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19615             }
19616         }
19617
19618         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19619                 + " reason=" + app.adjType);
19620
19621         // By default, we use the computed adjustment.  It may be changed if
19622         // there are applications dependent on our services or providers, but
19623         // this gives us a baseline and makes sure we don't get into an
19624         // infinite recursion.
19625         app.adjSeq = mAdjSeq;
19626         app.curRawAdj = adj;
19627         app.hasStartedServices = false;
19628
19629         if (mBackupTarget != null && app == mBackupTarget.app) {
19630             // If possible we want to avoid killing apps while they're being backed up
19631             if (adj > ProcessList.BACKUP_APP_ADJ) {
19632                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19633                 adj = ProcessList.BACKUP_APP_ADJ;
19634                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19635                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19636                 }
19637                 app.adjType = "backup";
19638                 app.cached = false;
19639             }
19640             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19641                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19642             }
19643         }
19644
19645         boolean mayBeTop = false;
19646
19647         for (int is = app.services.size()-1;
19648                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19649                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19650                         || procState > ActivityManager.PROCESS_STATE_TOP);
19651                 is--) {
19652             ServiceRecord s = app.services.valueAt(is);
19653             if (s.startRequested) {
19654                 app.hasStartedServices = true;
19655                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19656                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19657                 }
19658                 if (app.hasShownUi && app != mHomeProcess) {
19659                     // If this process has shown some UI, let it immediately
19660                     // go to the LRU list because it may be pretty heavy with
19661                     // UI stuff.  We'll tag it with a label just to help
19662                     // debug and understand what is going on.
19663                     if (adj > ProcessList.SERVICE_ADJ) {
19664                         app.adjType = "cch-started-ui-services";
19665                     }
19666                 } else {
19667                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19668                         // This service has seen some activity within
19669                         // recent memory, so we will keep its process ahead
19670                         // of the background processes.
19671                         if (adj > ProcessList.SERVICE_ADJ) {
19672                             adj = ProcessList.SERVICE_ADJ;
19673                             app.adjType = "started-services";
19674                             app.cached = false;
19675                         }
19676                     }
19677                     // If we have let the service slide into the background
19678                     // state, still have some text describing what it is doing
19679                     // even though the service no longer has an impact.
19680                     if (adj > ProcessList.SERVICE_ADJ) {
19681                         app.adjType = "cch-started-services";
19682                     }
19683                 }
19684             }
19685
19686             for (int conni = s.connections.size()-1;
19687                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19688                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19689                             || procState > ActivityManager.PROCESS_STATE_TOP);
19690                     conni--) {
19691                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19692                 for (int i = 0;
19693                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19694                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19695                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19696                         i++) {
19697                     // XXX should compute this based on the max of
19698                     // all connected clients.
19699                     ConnectionRecord cr = clist.get(i);
19700                     if (cr.binding.client == app) {
19701                         // Binding to ourself is not interesting.
19702                         continue;
19703                     }
19704
19705                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19706                         ProcessRecord client = cr.binding.client;
19707                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19708                                 TOP_APP, doingAll, now);
19709                         int clientProcState = client.curProcState;
19710                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19711                             // If the other app is cached for any reason, for purposes here
19712                             // we are going to consider it empty.  The specific cached state
19713                             // doesn't propagate except under certain conditions.
19714                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19715                         }
19716                         String adjType = null;
19717                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19718                             // Not doing bind OOM management, so treat
19719                             // this guy more like a started service.
19720                             if (app.hasShownUi && app != mHomeProcess) {
19721                                 // If this process has shown some UI, let it immediately
19722                                 // go to the LRU list because it may be pretty heavy with
19723                                 // UI stuff.  We'll tag it with a label just to help
19724                                 // debug and understand what is going on.
19725                                 if (adj > clientAdj) {
19726                                     adjType = "cch-bound-ui-services";
19727                                 }
19728                                 app.cached = false;
19729                                 clientAdj = adj;
19730                                 clientProcState = procState;
19731                             } else {
19732                                 if (now >= (s.lastActivity
19733                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19734                                     // This service has not seen activity within
19735                                     // recent memory, so allow it to drop to the
19736                                     // LRU list if there is no other reason to keep
19737                                     // it around.  We'll also tag it with a label just
19738                                     // to help debug and undertand what is going on.
19739                                     if (adj > clientAdj) {
19740                                         adjType = "cch-bound-services";
19741                                     }
19742                                     clientAdj = adj;
19743                                 }
19744                             }
19745                         }
19746                         if (adj > clientAdj) {
19747                             // If this process has recently shown UI, and
19748                             // the process that is binding to it is less
19749                             // important than being visible, then we don't
19750                             // care about the binding as much as we care
19751                             // about letting this process get into the LRU
19752                             // list to be killed and restarted if needed for
19753                             // memory.
19754                             if (app.hasShownUi && app != mHomeProcess
19755                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19756                                 adjType = "cch-bound-ui-services";
19757                             } else {
19758                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19759                                         |Context.BIND_IMPORTANT)) != 0) {
19760                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19761                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19762                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19763                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19764                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19765                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19766                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19767                                     adj = clientAdj;
19768                                 } else {
19769                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19770                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19771                                     }
19772                                 }
19773                                 if (!client.cached) {
19774                                     app.cached = false;
19775                                 }
19776                                 adjType = "service";
19777                             }
19778                         }
19779                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19780                             // This will treat important bound services identically to
19781                             // the top app, which may behave differently than generic
19782                             // foreground work.
19783                             if (client.curSchedGroup > schedGroup) {
19784                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19785                                     schedGroup = client.curSchedGroup;
19786                                 } else {
19787                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19788                                 }
19789                             }
19790                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19791                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19792                                     // Special handling of clients who are in the top state.
19793                                     // We *may* want to consider this process to be in the
19794                                     // top state as well, but only if there is not another
19795                                     // reason for it to be running.  Being on the top is a
19796                                     // special state, meaning you are specifically running
19797                                     // for the current top app.  If the process is already
19798                                     // running in the background for some other reason, it
19799                                     // is more important to continue considering it to be
19800                                     // in the background state.
19801                                     mayBeTop = true;
19802                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19803                                 } else {
19804                                     // Special handling for above-top states (persistent
19805                                     // processes).  These should not bring the current process
19806                                     // into the top state, since they are not on top.  Instead
19807                                     // give them the best state after that.
19808                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19809                                         clientProcState =
19810                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19811                                     } else if (mWakefulness
19812                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19813                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19814                                                     != 0) {
19815                                         clientProcState =
19816                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19817                                     } else {
19818                                         clientProcState =
19819                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19820                                     }
19821                                 }
19822                             }
19823                         } else {
19824                             if (clientProcState <
19825                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19826                                 clientProcState =
19827                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19828                             }
19829                         }
19830                         if (procState > clientProcState) {
19831                             procState = clientProcState;
19832                         }
19833                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19834                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19835                             app.pendingUiClean = true;
19836                         }
19837                         if (adjType != null) {
19838                             app.adjType = adjType;
19839                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19840                                     .REASON_SERVICE_IN_USE;
19841                             app.adjSource = cr.binding.client;
19842                             app.adjSourceProcState = clientProcState;
19843                             app.adjTarget = s.name;
19844                         }
19845                     }
19846                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19847                         app.treatLikeActivity = true;
19848                     }
19849                     final ActivityRecord a = cr.activity;
19850                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19851                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19852                             (a.visible || a.state == ActivityState.RESUMED ||
19853                              a.state == ActivityState.PAUSING)) {
19854                             adj = ProcessList.FOREGROUND_APP_ADJ;
19855                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19856                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19857                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19858                                 } else {
19859                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19860                                 }
19861                             }
19862                             app.cached = false;
19863                             app.adjType = "service";
19864                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19865                                     .REASON_SERVICE_IN_USE;
19866                             app.adjSource = a;
19867                             app.adjSourceProcState = procState;
19868                             app.adjTarget = s.name;
19869                         }
19870                     }
19871                 }
19872             }
19873         }
19874
19875         for (int provi = app.pubProviders.size()-1;
19876                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19877                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19878                         || procState > ActivityManager.PROCESS_STATE_TOP);
19879                 provi--) {
19880             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19881             for (int i = cpr.connections.size()-1;
19882                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19883                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19884                             || procState > ActivityManager.PROCESS_STATE_TOP);
19885                     i--) {
19886                 ContentProviderConnection conn = cpr.connections.get(i);
19887                 ProcessRecord client = conn.client;
19888                 if (client == app) {
19889                     // Being our own client is not interesting.
19890                     continue;
19891                 }
19892                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19893                 int clientProcState = client.curProcState;
19894                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19895                     // If the other app is cached for any reason, for purposes here
19896                     // we are going to consider it empty.
19897                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19898                 }
19899                 if (adj > clientAdj) {
19900                     if (app.hasShownUi && app != mHomeProcess
19901                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19902                         app.adjType = "cch-ui-provider";
19903                     } else {
19904                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19905                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19906                         app.adjType = "provider";
19907                     }
19908                     app.cached &= client.cached;
19909                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19910                             .REASON_PROVIDER_IN_USE;
19911                     app.adjSource = client;
19912                     app.adjSourceProcState = clientProcState;
19913                     app.adjTarget = cpr.name;
19914                 }
19915                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19916                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19917                         // Special handling of clients who are in the top state.
19918                         // We *may* want to consider this process to be in the
19919                         // top state as well, but only if there is not another
19920                         // reason for it to be running.  Being on the top is a
19921                         // special state, meaning you are specifically running
19922                         // for the current top app.  If the process is already
19923                         // running in the background for some other reason, it
19924                         // is more important to continue considering it to be
19925                         // in the background state.
19926                         mayBeTop = true;
19927                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19928                     } else {
19929                         // Special handling for above-top states (persistent
19930                         // processes).  These should not bring the current process
19931                         // into the top state, since they are not on top.  Instead
19932                         // give them the best state after that.
19933                         clientProcState =
19934                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19935                     }
19936                 }
19937                 if (procState > clientProcState) {
19938                     procState = clientProcState;
19939                 }
19940                 if (client.curSchedGroup > schedGroup) {
19941                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19942                 }
19943             }
19944             // If the provider has external (non-framework) process
19945             // dependencies, ensure that its adjustment is at least
19946             // FOREGROUND_APP_ADJ.
19947             if (cpr.hasExternalProcessHandles()) {
19948                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19949                     adj = ProcessList.FOREGROUND_APP_ADJ;
19950                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19951                     app.cached = false;
19952                     app.adjType = "provider";
19953                     app.adjTarget = cpr.name;
19954                 }
19955                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19956                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19957                 }
19958             }
19959         }
19960
19961         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19962             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19963                 adj = ProcessList.PREVIOUS_APP_ADJ;
19964                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19965                 app.cached = false;
19966                 app.adjType = "provider";
19967             }
19968             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19969                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19970             }
19971         }
19972
19973         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19974             // A client of one of our services or providers is in the top state.  We
19975             // *may* want to be in the top state, but not if we are already running in
19976             // the background for some other reason.  For the decision here, we are going
19977             // to pick out a few specific states that we want to remain in when a client
19978             // is top (states that tend to be longer-term) and otherwise allow it to go
19979             // to the top state.
19980             switch (procState) {
19981                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19982                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19983                 case ActivityManager.PROCESS_STATE_SERVICE:
19984                     // These all are longer-term states, so pull them up to the top
19985                     // of the background states, but not all the way to the top state.
19986                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19987                     break;
19988                 default:
19989                     // Otherwise, top is a better choice, so take it.
19990                     procState = ActivityManager.PROCESS_STATE_TOP;
19991                     break;
19992             }
19993         }
19994
19995         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19996             if (app.hasClientActivities) {
19997                 // This is a cached process, but with client activities.  Mark it so.
19998                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19999                 app.adjType = "cch-client-act";
20000             } else if (app.treatLikeActivity) {
20001                 // This is a cached process, but somebody wants us to treat it like it has
20002                 // an activity, okay!
20003                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20004                 app.adjType = "cch-as-act";
20005             }
20006         }
20007
20008         if (adj == ProcessList.SERVICE_ADJ) {
20009             if (doingAll) {
20010                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20011                 mNewNumServiceProcs++;
20012                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20013                 if (!app.serviceb) {
20014                     // This service isn't far enough down on the LRU list to
20015                     // normally be a B service, but if we are low on RAM and it
20016                     // is large we want to force it down since we would prefer to
20017                     // keep launcher over it.
20018                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20019                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20020                         app.serviceHighRam = true;
20021                         app.serviceb = true;
20022                         //Slog.i(TAG, "ADJ " + app + " high ram!");
20023                     } else {
20024                         mNewNumAServiceProcs++;
20025                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
20026                     }
20027                 } else {
20028                     app.serviceHighRam = false;
20029                 }
20030             }
20031             if (app.serviceb) {
20032                 adj = ProcessList.SERVICE_B_ADJ;
20033             }
20034         }
20035
20036         app.curRawAdj = adj;
20037
20038         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20039         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20040         if (adj > app.maxAdj) {
20041             adj = app.maxAdj;
20042             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20043                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20044             }
20045         }
20046
20047         // Do final modification to adj.  Everything we do between here and applying
20048         // the final setAdj must be done in this function, because we will also use
20049         // it when computing the final cached adj later.  Note that we don't need to
20050         // worry about this for max adj above, since max adj will always be used to
20051         // keep it out of the cached vaues.
20052         app.curAdj = app.modifyRawOomAdj(adj);
20053         app.curSchedGroup = schedGroup;
20054         app.curProcState = procState;
20055         app.foregroundActivities = foregroundActivities;
20056
20057         return app.curRawAdj;
20058     }
20059
20060     /**
20061      * Record new PSS sample for a process.
20062      */
20063     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20064             long now) {
20065         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20066                 swapPss * 1024);
20067         proc.lastPssTime = now;
20068         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20069         if (DEBUG_PSS) Slog.d(TAG_PSS,
20070                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20071                 + " state=" + ProcessList.makeProcStateString(procState));
20072         if (proc.initialIdlePss == 0) {
20073             proc.initialIdlePss = pss;
20074         }
20075         proc.lastPss = pss;
20076         proc.lastSwapPss = swapPss;
20077         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20078             proc.lastCachedPss = pss;
20079             proc.lastCachedSwapPss = swapPss;
20080         }
20081
20082         final SparseArray<Pair<Long, String>> watchUids
20083                 = mMemWatchProcesses.getMap().get(proc.processName);
20084         Long check = null;
20085         if (watchUids != null) {
20086             Pair<Long, String> val = watchUids.get(proc.uid);
20087             if (val == null) {
20088                 val = watchUids.get(0);
20089             }
20090             if (val != null) {
20091                 check = val.first;
20092             }
20093         }
20094         if (check != null) {
20095             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20096                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20097                 if (!isDebuggable) {
20098                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20099                         isDebuggable = true;
20100                     }
20101                 }
20102                 if (isDebuggable) {
20103                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20104                     final ProcessRecord myProc = proc;
20105                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20106                     mMemWatchDumpProcName = proc.processName;
20107                     mMemWatchDumpFile = heapdumpFile.toString();
20108                     mMemWatchDumpPid = proc.pid;
20109                     mMemWatchDumpUid = proc.uid;
20110                     BackgroundThread.getHandler().post(new Runnable() {
20111                         @Override
20112                         public void run() {
20113                             revokeUriPermission(ActivityThread.currentActivityThread()
20114                                             .getApplicationThread(),
20115                                     DumpHeapActivity.JAVA_URI,
20116                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20117                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20118                                     UserHandle.myUserId());
20119                             ParcelFileDescriptor fd = null;
20120                             try {
20121                                 heapdumpFile.delete();
20122                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20123                                         ParcelFileDescriptor.MODE_CREATE |
20124                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20125                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20126                                                 ParcelFileDescriptor.MODE_APPEND);
20127                                 IApplicationThread thread = myProc.thread;
20128                                 if (thread != null) {
20129                                     try {
20130                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20131                                                 "Requesting dump heap from "
20132                                                 + myProc + " to " + heapdumpFile);
20133                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20134                                     } catch (RemoteException e) {
20135                                     }
20136                                 }
20137                             } catch (FileNotFoundException e) {
20138                                 e.printStackTrace();
20139                             } finally {
20140                                 if (fd != null) {
20141                                     try {
20142                                         fd.close();
20143                                     } catch (IOException e) {
20144                                     }
20145                                 }
20146                             }
20147                         }
20148                     });
20149                 } else {
20150                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20151                             + ", but debugging not enabled");
20152                 }
20153             }
20154         }
20155     }
20156
20157     /**
20158      * Schedule PSS collection of a process.
20159      */
20160     void requestPssLocked(ProcessRecord proc, int procState) {
20161         if (mPendingPssProcesses.contains(proc)) {
20162             return;
20163         }
20164         if (mPendingPssProcesses.size() == 0) {
20165             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20166         }
20167         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20168         proc.pssProcState = procState;
20169         mPendingPssProcesses.add(proc);
20170     }
20171
20172     /**
20173      * Schedule PSS collection of all processes.
20174      */
20175     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20176         if (!always) {
20177             if (now < (mLastFullPssTime +
20178                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20179                 return;
20180             }
20181         }
20182         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20183         mLastFullPssTime = now;
20184         mFullPssPending = true;
20185         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20186         mPendingPssProcesses.clear();
20187         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20188             ProcessRecord app = mLruProcesses.get(i);
20189             if (app.thread == null
20190                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20191                 continue;
20192             }
20193             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20194                 app.pssProcState = app.setProcState;
20195                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20196                         mTestPssMode, isSleepingLocked(), now);
20197                 mPendingPssProcesses.add(app);
20198             }
20199         }
20200         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20201     }
20202
20203     public void setTestPssMode(boolean enabled) {
20204         synchronized (this) {
20205             mTestPssMode = enabled;
20206             if (enabled) {
20207                 // Whenever we enable the mode, we want to take a snapshot all of current
20208                 // process mem use.
20209                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20210             }
20211         }
20212     }
20213
20214     /**
20215      * Ask a given process to GC right now.
20216      */
20217     final void performAppGcLocked(ProcessRecord app) {
20218         try {
20219             app.lastRequestedGc = SystemClock.uptimeMillis();
20220             if (app.thread != null) {
20221                 if (app.reportLowMemory) {
20222                     app.reportLowMemory = false;
20223                     app.thread.scheduleLowMemory();
20224                 } else {
20225                     app.thread.processInBackground();
20226                 }
20227             }
20228         } catch (Exception e) {
20229             // whatever.
20230         }
20231     }
20232
20233     /**
20234      * Returns true if things are idle enough to perform GCs.
20235      */
20236     private final boolean canGcNowLocked() {
20237         boolean processingBroadcasts = false;
20238         for (BroadcastQueue q : mBroadcastQueues) {
20239             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20240                 processingBroadcasts = true;
20241             }
20242         }
20243         return !processingBroadcasts
20244                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20245     }
20246
20247     /**
20248      * Perform GCs on all processes that are waiting for it, but only
20249      * if things are idle.
20250      */
20251     final void performAppGcsLocked() {
20252         final int N = mProcessesToGc.size();
20253         if (N <= 0) {
20254             return;
20255         }
20256         if (canGcNowLocked()) {
20257             while (mProcessesToGc.size() > 0) {
20258                 ProcessRecord proc = mProcessesToGc.remove(0);
20259                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20260                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20261                             <= SystemClock.uptimeMillis()) {
20262                         // To avoid spamming the system, we will GC processes one
20263                         // at a time, waiting a few seconds between each.
20264                         performAppGcLocked(proc);
20265                         scheduleAppGcsLocked();
20266                         return;
20267                     } else {
20268                         // It hasn't been long enough since we last GCed this
20269                         // process...  put it in the list to wait for its time.
20270                         addProcessToGcListLocked(proc);
20271                         break;
20272                     }
20273                 }
20274             }
20275
20276             scheduleAppGcsLocked();
20277         }
20278     }
20279
20280     /**
20281      * If all looks good, perform GCs on all processes waiting for them.
20282      */
20283     final void performAppGcsIfAppropriateLocked() {
20284         if (canGcNowLocked()) {
20285             performAppGcsLocked();
20286             return;
20287         }
20288         // Still not idle, wait some more.
20289         scheduleAppGcsLocked();
20290     }
20291
20292     /**
20293      * Schedule the execution of all pending app GCs.
20294      */
20295     final void scheduleAppGcsLocked() {
20296         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20297
20298         if (mProcessesToGc.size() > 0) {
20299             // Schedule a GC for the time to the next process.
20300             ProcessRecord proc = mProcessesToGc.get(0);
20301             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20302
20303             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20304             long now = SystemClock.uptimeMillis();
20305             if (when < (now+GC_TIMEOUT)) {
20306                 when = now + GC_TIMEOUT;
20307             }
20308             mHandler.sendMessageAtTime(msg, when);
20309         }
20310     }
20311
20312     /**
20313      * Add a process to the array of processes waiting to be GCed.  Keeps the
20314      * list in sorted order by the last GC time.  The process can't already be
20315      * on the list.
20316      */
20317     final void addProcessToGcListLocked(ProcessRecord proc) {
20318         boolean added = false;
20319         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20320             if (mProcessesToGc.get(i).lastRequestedGc <
20321                     proc.lastRequestedGc) {
20322                 added = true;
20323                 mProcessesToGc.add(i+1, proc);
20324                 break;
20325             }
20326         }
20327         if (!added) {
20328             mProcessesToGc.add(0, proc);
20329         }
20330     }
20331
20332     /**
20333      * Set up to ask a process to GC itself.  This will either do it
20334      * immediately, or put it on the list of processes to gc the next
20335      * time things are idle.
20336      */
20337     final void scheduleAppGcLocked(ProcessRecord app) {
20338         long now = SystemClock.uptimeMillis();
20339         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20340             return;
20341         }
20342         if (!mProcessesToGc.contains(app)) {
20343             addProcessToGcListLocked(app);
20344             scheduleAppGcsLocked();
20345         }
20346     }
20347
20348     final void checkExcessivePowerUsageLocked(boolean doKills) {
20349         updateCpuStatsNow();
20350
20351         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20352         boolean doWakeKills = doKills;
20353         boolean doCpuKills = doKills;
20354         if (mLastPowerCheckRealtime == 0) {
20355             doWakeKills = false;
20356         }
20357         if (mLastPowerCheckUptime == 0) {
20358             doCpuKills = false;
20359         }
20360         if (stats.isScreenOn()) {
20361             doWakeKills = false;
20362         }
20363         final long curRealtime = SystemClock.elapsedRealtime();
20364         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20365         final long curUptime = SystemClock.uptimeMillis();
20366         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20367         mLastPowerCheckRealtime = curRealtime;
20368         mLastPowerCheckUptime = curUptime;
20369         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20370             doWakeKills = false;
20371         }
20372         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20373             doCpuKills = false;
20374         }
20375         int i = mLruProcesses.size();
20376         while (i > 0) {
20377             i--;
20378             ProcessRecord app = mLruProcesses.get(i);
20379             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20380                 long wtime;
20381                 synchronized (stats) {
20382                     wtime = stats.getProcessWakeTime(app.info.uid,
20383                             app.pid, curRealtime);
20384                 }
20385                 long wtimeUsed = wtime - app.lastWakeTime;
20386                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20387                 if (DEBUG_POWER) {
20388                     StringBuilder sb = new StringBuilder(128);
20389                     sb.append("Wake for ");
20390                     app.toShortString(sb);
20391                     sb.append(": over ");
20392                     TimeUtils.formatDuration(realtimeSince, sb);
20393                     sb.append(" used ");
20394                     TimeUtils.formatDuration(wtimeUsed, sb);
20395                     sb.append(" (");
20396                     sb.append((wtimeUsed*100)/realtimeSince);
20397                     sb.append("%)");
20398                     Slog.i(TAG_POWER, sb.toString());
20399                     sb.setLength(0);
20400                     sb.append("CPU for ");
20401                     app.toShortString(sb);
20402                     sb.append(": over ");
20403                     TimeUtils.formatDuration(uptimeSince, sb);
20404                     sb.append(" used ");
20405                     TimeUtils.formatDuration(cputimeUsed, sb);
20406                     sb.append(" (");
20407                     sb.append((cputimeUsed*100)/uptimeSince);
20408                     sb.append("%)");
20409                     Slog.i(TAG_POWER, sb.toString());
20410                 }
20411                 // If a process has held a wake lock for more
20412                 // than 50% of the time during this period,
20413                 // that sounds bad.  Kill!
20414                 if (doWakeKills && realtimeSince > 0
20415                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20416                     synchronized (stats) {
20417                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20418                                 realtimeSince, wtimeUsed);
20419                     }
20420                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20421                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20422                 } else if (doCpuKills && uptimeSince > 0
20423                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20424                     synchronized (stats) {
20425                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20426                                 uptimeSince, cputimeUsed);
20427                     }
20428                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20429                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20430                 } else {
20431                     app.lastWakeTime = wtime;
20432                     app.lastCpuTime = app.curCpuTime;
20433                 }
20434             }
20435         }
20436     }
20437
20438     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20439             long nowElapsed) {
20440         boolean success = true;
20441
20442         if (app.curRawAdj != app.setRawAdj) {
20443             app.setRawAdj = app.curRawAdj;
20444         }
20445
20446         int changes = 0;
20447
20448         if (app.curAdj != app.setAdj) {
20449             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20450             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20451                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20452                     + app.adjType);
20453             app.setAdj = app.curAdj;
20454             app.verifiedAdj = ProcessList.INVALID_ADJ;
20455         }
20456
20457         if (app.setSchedGroup != app.curSchedGroup) {
20458             int oldSchedGroup = app.setSchedGroup;
20459             app.setSchedGroup = app.curSchedGroup;
20460             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20461                     "Setting sched group of " + app.processName
20462                     + " to " + app.curSchedGroup);
20463             if (app.waitingToKill != null && app.curReceiver == null
20464                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20465                 app.kill(app.waitingToKill, true);
20466                 success = false;
20467             } else {
20468                 int processGroup;
20469                 switch (app.curSchedGroup) {
20470                     case ProcessList.SCHED_GROUP_BACKGROUND:
20471                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20472                         break;
20473                     case ProcessList.SCHED_GROUP_TOP_APP:
20474                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20475                         processGroup = Process.THREAD_GROUP_TOP_APP;
20476                         break;
20477                     default:
20478                         processGroup = Process.THREAD_GROUP_DEFAULT;
20479                         break;
20480                 }
20481                 long oldId = Binder.clearCallingIdentity();
20482                 try {
20483                     Process.setProcessGroup(app.pid, processGroup);
20484                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20485                         // do nothing if we already switched to RT
20486                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20487                             // Switch VR thread for app to SCHED_FIFO
20488                             if (mInVrMode && app.vrThreadTid != 0) {
20489                                 try {
20490                                     Process.setThreadScheduler(app.vrThreadTid,
20491                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20492                                 } catch (IllegalArgumentException e) {
20493                                     // thread died, ignore
20494                                 }
20495                             }
20496                             if (mUseFifoUiScheduling) {
20497                                 // Switch UI pipeline for app to SCHED_FIFO
20498                                 app.savedPriority = Process.getThreadPriority(app.pid);
20499                                 try {
20500                                     Process.setThreadScheduler(app.pid,
20501                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20502                                 } catch (IllegalArgumentException e) {
20503                                     // thread died, ignore
20504                                 }
20505                                 if (app.renderThreadTid != 0) {
20506                                     try {
20507                                         Process.setThreadScheduler(app.renderThreadTid,
20508                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20509                                     } catch (IllegalArgumentException e) {
20510                                         // thread died, ignore
20511                                     }
20512                                     if (DEBUG_OOM_ADJ) {
20513                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20514                                             app.renderThreadTid + ") to FIFO");
20515                                     }
20516                                 } else {
20517                                     if (DEBUG_OOM_ADJ) {
20518                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20519                                     }
20520                                 }
20521                             } else {
20522                                 // Boost priority for top app UI and render threads
20523                                 Process.setThreadPriority(app.pid, -10);
20524                                 if (app.renderThreadTid != 0) {
20525                                     try {
20526                                         Process.setThreadPriority(app.renderThreadTid, -10);
20527                                     } catch (IllegalArgumentException e) {
20528                                         // thread died, ignore
20529                                     }
20530                                 }
20531                             }
20532                         }
20533                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20534                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20535                         // Reset VR thread to SCHED_OTHER
20536                         // Safe to do even if we're not in VR mode
20537                         if (app.vrThreadTid != 0) {
20538                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20539                         }
20540                         if (mUseFifoUiScheduling) {
20541                             // Reset UI pipeline to SCHED_OTHER
20542                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20543                             Process.setThreadPriority(app.pid, app.savedPriority);
20544                             if (app.renderThreadTid != 0) {
20545                                 Process.setThreadScheduler(app.renderThreadTid,
20546                                     Process.SCHED_OTHER, 0);
20547                                 Process.setThreadPriority(app.renderThreadTid, -4);
20548                             }
20549                         } else {
20550                             // Reset priority for top app UI and render threads
20551                             Process.setThreadPriority(app.pid, 0);
20552                             if (app.renderThreadTid != 0) {
20553                                 Process.setThreadPriority(app.renderThreadTid, 0);
20554                             }
20555                         }
20556                     }
20557                 } catch (Exception e) {
20558                     Slog.w(TAG, "Failed setting process group of " + app.pid
20559                             + " to " + app.curSchedGroup);
20560                     e.printStackTrace();
20561                 } finally {
20562                     Binder.restoreCallingIdentity(oldId);
20563                 }
20564             }
20565         }
20566         if (app.repForegroundActivities != app.foregroundActivities) {
20567             app.repForegroundActivities = app.foregroundActivities;
20568             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20569         }
20570         if (app.repProcState != app.curProcState) {
20571             app.repProcState = app.curProcState;
20572             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20573             if (app.thread != null) {
20574                 try {
20575                     if (false) {
20576                         //RuntimeException h = new RuntimeException("here");
20577                         Slog.i(TAG, "Sending new process state " + app.repProcState
20578                                 + " to " + app /*, h*/);
20579                     }
20580                     app.thread.setProcessState(app.repProcState);
20581                 } catch (RemoteException e) {
20582                 }
20583             }
20584         }
20585         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20586                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20587             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20588                 // Experimental code to more aggressively collect pss while
20589                 // running test...  the problem is that this tends to collect
20590                 // the data right when a process is transitioning between process
20591                 // states, which well tend to give noisy data.
20592                 long start = SystemClock.uptimeMillis();
20593                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20594                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20595                 mPendingPssProcesses.remove(app);
20596                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20597                         + " to " + app.curProcState + ": "
20598                         + (SystemClock.uptimeMillis()-start) + "ms");
20599             }
20600             app.lastStateTime = now;
20601             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20602                     mTestPssMode, isSleepingLocked(), now);
20603             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20604                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20605                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20606                     + (app.nextPssTime-now) + ": " + app);
20607         } else {
20608             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20609                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20610                     mTestPssMode)))) {
20611                 requestPssLocked(app, app.setProcState);
20612                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20613                         mTestPssMode, isSleepingLocked(), now);
20614             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20615                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20616         }
20617         if (app.setProcState != app.curProcState) {
20618             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20619                     "Proc state change of " + app.processName
20620                             + " to " + app.curProcState);
20621             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20622             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20623             if (setImportant && !curImportant) {
20624                 // This app is no longer something we consider important enough to allow to
20625                 // use arbitrary amounts of battery power.  Note
20626                 // its current wake lock time to later know to kill it if
20627                 // it is not behaving well.
20628                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20629                 synchronized (stats) {
20630                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20631                             app.pid, nowElapsed);
20632                 }
20633                 app.lastCpuTime = app.curCpuTime;
20634
20635             }
20636             // Inform UsageStats of important process state change
20637             // Must be called before updating setProcState
20638             maybeUpdateUsageStatsLocked(app, nowElapsed);
20639
20640             app.setProcState = app.curProcState;
20641             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20642                 app.notCachedSinceIdle = false;
20643             }
20644             if (!doingAll) {
20645                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20646             } else {
20647                 app.procStateChanged = true;
20648             }
20649         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20650                 > USAGE_STATS_INTERACTION_INTERVAL) {
20651             // For apps that sit around for a long time in the interactive state, we need
20652             // to report this at least once a day so they don't go idle.
20653             maybeUpdateUsageStatsLocked(app, nowElapsed);
20654         }
20655
20656         if (changes != 0) {
20657             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20658                     "Changes in " + app + ": " + changes);
20659             int i = mPendingProcessChanges.size()-1;
20660             ProcessChangeItem item = null;
20661             while (i >= 0) {
20662                 item = mPendingProcessChanges.get(i);
20663                 if (item.pid == app.pid) {
20664                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20665                             "Re-using existing item: " + item);
20666                     break;
20667                 }
20668                 i--;
20669             }
20670             if (i < 0) {
20671                 // No existing item in pending changes; need a new one.
20672                 final int NA = mAvailProcessChanges.size();
20673                 if (NA > 0) {
20674                     item = mAvailProcessChanges.remove(NA-1);
20675                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20676                             "Retrieving available item: " + item);
20677                 } else {
20678                     item = new ProcessChangeItem();
20679                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20680                             "Allocating new item: " + item);
20681                 }
20682                 item.changes = 0;
20683                 item.pid = app.pid;
20684                 item.uid = app.info.uid;
20685                 if (mPendingProcessChanges.size() == 0) {
20686                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20687                             "*** Enqueueing dispatch processes changed!");
20688                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20689                 }
20690                 mPendingProcessChanges.add(item);
20691             }
20692             item.changes |= changes;
20693             item.processState = app.repProcState;
20694             item.foregroundActivities = app.repForegroundActivities;
20695             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20696                     "Item " + Integer.toHexString(System.identityHashCode(item))
20697                     + " " + app.toShortString() + ": changes=" + item.changes
20698                     + " procState=" + item.processState
20699                     + " foreground=" + item.foregroundActivities
20700                     + " type=" + app.adjType + " source=" + app.adjSource
20701                     + " target=" + app.adjTarget);
20702         }
20703
20704         return success;
20705     }
20706
20707     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20708         final UidRecord.ChangeItem pendingChange;
20709         if (uidRec == null || uidRec.pendingChange == null) {
20710             if (mPendingUidChanges.size() == 0) {
20711                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20712                         "*** Enqueueing dispatch uid changed!");
20713                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20714             }
20715             final int NA = mAvailUidChanges.size();
20716             if (NA > 0) {
20717                 pendingChange = mAvailUidChanges.remove(NA-1);
20718                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20719                         "Retrieving available item: " + pendingChange);
20720             } else {
20721                 pendingChange = new UidRecord.ChangeItem();
20722                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20723                         "Allocating new item: " + pendingChange);
20724             }
20725             if (uidRec != null) {
20726                 uidRec.pendingChange = pendingChange;
20727                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20728                     // If this uid is going away, and we haven't yet reported it is gone,
20729                     // then do so now.
20730                     change = UidRecord.CHANGE_GONE_IDLE;
20731                 }
20732             } else if (uid < 0) {
20733                 throw new IllegalArgumentException("No UidRecord or uid");
20734             }
20735             pendingChange.uidRecord = uidRec;
20736             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20737             mPendingUidChanges.add(pendingChange);
20738         } else {
20739             pendingChange = uidRec.pendingChange;
20740             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20741                 change = UidRecord.CHANGE_GONE_IDLE;
20742             }
20743         }
20744         pendingChange.change = change;
20745         pendingChange.processState = uidRec != null
20746                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20747     }
20748
20749     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20750             String authority) {
20751         if (app == null) return;
20752         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20753             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20754             if (userState == null) return;
20755             final long now = SystemClock.elapsedRealtime();
20756             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20757             if (lastReported == null || lastReported < now - 60 * 1000L) {
20758                 if (mSystemReady) {
20759                     // Cannot touch the user stats if not system ready
20760                     mUsageStatsService.reportContentProviderUsage(
20761                             authority, providerPkgName, app.userId);
20762                 }
20763                 userState.mProviderLastReportedFg.put(authority, now);
20764             }
20765         }
20766     }
20767
20768     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20769         if (DEBUG_USAGE_STATS) {
20770             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20771                     + "] state changes: old = " + app.setProcState + ", new = "
20772                     + app.curProcState);
20773         }
20774         if (mUsageStatsService == null) {
20775             return;
20776         }
20777         boolean isInteraction;
20778         // To avoid some abuse patterns, we are going to be careful about what we consider
20779         // to be an app interaction.  Being the top activity doesn't count while the display
20780         // is sleeping, nor do short foreground services.
20781         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20782             isInteraction = true;
20783             app.fgInteractionTime = 0;
20784         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20785             if (app.fgInteractionTime == 0) {
20786                 app.fgInteractionTime = nowElapsed;
20787                 isInteraction = false;
20788             } else {
20789                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20790             }
20791         } else {
20792             // If the app was being forced to the foreground, by say a Toast, then
20793             // no need to treat it as an interaction
20794             isInteraction = app.forcingToForeground == null
20795                     && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20796             app.fgInteractionTime = 0;
20797         }
20798         if (isInteraction && (!app.reportedInteraction
20799                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20800             app.interactionEventTime = nowElapsed;
20801             String[] packages = app.getPackageList();
20802             if (packages != null) {
20803                 for (int i = 0; i < packages.length; i++) {
20804                     mUsageStatsService.reportEvent(packages[i], app.userId,
20805                             UsageEvents.Event.SYSTEM_INTERACTION);
20806                 }
20807             }
20808         }
20809         app.reportedInteraction = isInteraction;
20810         if (!isInteraction) {
20811             app.interactionEventTime = 0;
20812         }
20813     }
20814
20815     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20816         if (proc.thread != null) {
20817             if (proc.baseProcessTracker != null) {
20818                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20819             }
20820         }
20821     }
20822
20823     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20824             ProcessRecord TOP_APP, boolean doingAll, long now) {
20825         if (app.thread == null) {
20826             return false;
20827         }
20828
20829         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20830
20831         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20832     }
20833
20834     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20835             boolean oomAdj) {
20836         if (isForeground != proc.foregroundServices) {
20837             proc.foregroundServices = isForeground;
20838             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20839                     proc.info.uid);
20840             if (isForeground) {
20841                 if (curProcs == null) {
20842                     curProcs = new ArrayList<ProcessRecord>();
20843                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20844                 }
20845                 if (!curProcs.contains(proc)) {
20846                     curProcs.add(proc);
20847                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20848                             proc.info.packageName, proc.info.uid);
20849                 }
20850             } else {
20851                 if (curProcs != null) {
20852                     if (curProcs.remove(proc)) {
20853                         mBatteryStatsService.noteEvent(
20854                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20855                                 proc.info.packageName, proc.info.uid);
20856                         if (curProcs.size() <= 0) {
20857                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20858                         }
20859                     }
20860                 }
20861             }
20862             if (oomAdj) {
20863                 updateOomAdjLocked();
20864             }
20865         }
20866     }
20867
20868     private final ActivityRecord resumedAppLocked() {
20869         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20870         String pkg;
20871         int uid;
20872         if (act != null) {
20873             pkg = act.packageName;
20874             uid = act.info.applicationInfo.uid;
20875         } else {
20876             pkg = null;
20877             uid = -1;
20878         }
20879         // Has the UID or resumed package name changed?
20880         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20881                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20882             if (mCurResumedPackage != null) {
20883                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20884                         mCurResumedPackage, mCurResumedUid);
20885             }
20886             mCurResumedPackage = pkg;
20887             mCurResumedUid = uid;
20888             if (mCurResumedPackage != null) {
20889                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20890                         mCurResumedPackage, mCurResumedUid);
20891             }
20892         }
20893         return act;
20894     }
20895
20896     final boolean updateOomAdjLocked(ProcessRecord app) {
20897         final ActivityRecord TOP_ACT = resumedAppLocked();
20898         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20899         final boolean wasCached = app.cached;
20900
20901         mAdjSeq++;
20902
20903         // This is the desired cached adjusment we want to tell it to use.
20904         // If our app is currently cached, we know it, and that is it.  Otherwise,
20905         // we don't know it yet, and it needs to now be cached we will then
20906         // need to do a complete oom adj.
20907         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20908                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20909         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20910                 SystemClock.uptimeMillis());
20911         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20912             // Changed to/from cached state, so apps after it in the LRU
20913             // list may also be changed.
20914             updateOomAdjLocked();
20915         }
20916         return success;
20917     }
20918
20919     final void updateOomAdjLocked() {
20920         final ActivityRecord TOP_ACT = resumedAppLocked();
20921         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20922         final long now = SystemClock.uptimeMillis();
20923         final long nowElapsed = SystemClock.elapsedRealtime();
20924         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20925         final int N = mLruProcesses.size();
20926
20927         if (false) {
20928             RuntimeException e = new RuntimeException();
20929             e.fillInStackTrace();
20930             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20931         }
20932
20933         // Reset state in all uid records.
20934         for (int i=mActiveUids.size()-1; i>=0; i--) {
20935             final UidRecord uidRec = mActiveUids.valueAt(i);
20936             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20937                     "Starting update of " + uidRec);
20938             uidRec.reset();
20939         }
20940
20941         mStackSupervisor.rankTaskLayersIfNeeded();
20942
20943         mAdjSeq++;
20944         mNewNumServiceProcs = 0;
20945         mNewNumAServiceProcs = 0;
20946
20947         final int emptyProcessLimit;
20948         final int cachedProcessLimit;
20949         if (mProcessLimit <= 0) {
20950             emptyProcessLimit = cachedProcessLimit = 0;
20951         } else if (mProcessLimit == 1) {
20952             emptyProcessLimit = 1;
20953             cachedProcessLimit = 0;
20954         } else {
20955             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20956             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20957         }
20958
20959         // Let's determine how many processes we have running vs.
20960         // how many slots we have for background processes; we may want
20961         // to put multiple processes in a slot of there are enough of
20962         // them.
20963         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20964                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20965         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20966         if (numEmptyProcs > cachedProcessLimit) {
20967             // If there are more empty processes than our limit on cached
20968             // processes, then use the cached process limit for the factor.
20969             // This ensures that the really old empty processes get pushed
20970             // down to the bottom, so if we are running low on memory we will
20971             // have a better chance at keeping around more cached processes
20972             // instead of a gazillion empty processes.
20973             numEmptyProcs = cachedProcessLimit;
20974         }
20975         int emptyFactor = numEmptyProcs/numSlots;
20976         if (emptyFactor < 1) emptyFactor = 1;
20977         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20978         if (cachedFactor < 1) cachedFactor = 1;
20979         int stepCached = 0;
20980         int stepEmpty = 0;
20981         int numCached = 0;
20982         int numEmpty = 0;
20983         int numTrimming = 0;
20984
20985         mNumNonCachedProcs = 0;
20986         mNumCachedHiddenProcs = 0;
20987
20988         // First update the OOM adjustment for each of the
20989         // application processes based on their current state.
20990         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20991         int nextCachedAdj = curCachedAdj+1;
20992         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20993         int nextEmptyAdj = curEmptyAdj+2;
20994         for (int i=N-1; i>=0; i--) {
20995             ProcessRecord app = mLruProcesses.get(i);
20996             if (app == null) {
20997                 continue;
20998             }
20999             if (!app.killedByAm && app.thread != null) {
21000                 app.procStateChanged = false;
21001                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21002
21003                 // If we haven't yet assigned the final cached adj
21004                 // to the process, do that now.
21005                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21006                     switch (app.curProcState) {
21007                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21008                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21009                             // This process is a cached process holding activities...
21010                             // assign it the next cached value for that type, and then
21011                             // step that cached level.
21012                             app.curRawAdj = curCachedAdj;
21013                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21014                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21015                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21016                                     + ")");
21017                             if (curCachedAdj != nextCachedAdj) {
21018                                 stepCached++;
21019                                 if (stepCached >= cachedFactor) {
21020                                     stepCached = 0;
21021                                     curCachedAdj = nextCachedAdj;
21022                                     nextCachedAdj += 2;
21023                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21024                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21025                                     }
21026                                 }
21027                             }
21028                             break;
21029                         default:
21030                             // For everything else, assign next empty cached process
21031                             // level and bump that up.  Note that this means that
21032                             // long-running services that have dropped down to the
21033                             // cached level will be treated as empty (since their process
21034                             // state is still as a service), which is what we want.
21035                             app.curRawAdj = curEmptyAdj;
21036                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21037                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21038                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21039                                     + ")");
21040                             if (curEmptyAdj != nextEmptyAdj) {
21041                                 stepEmpty++;
21042                                 if (stepEmpty >= emptyFactor) {
21043                                     stepEmpty = 0;
21044                                     curEmptyAdj = nextEmptyAdj;
21045                                     nextEmptyAdj += 2;
21046                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21047                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21048                                     }
21049                                 }
21050                             }
21051                             break;
21052                     }
21053                 }
21054
21055                 applyOomAdjLocked(app, true, now, nowElapsed);
21056
21057                 // Count the number of process types.
21058                 switch (app.curProcState) {
21059                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21060                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21061                         mNumCachedHiddenProcs++;
21062                         numCached++;
21063                         if (numCached > cachedProcessLimit) {
21064                             app.kill("cached #" + numCached, true);
21065                         }
21066                         break;
21067                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21068                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21069                                 && app.lastActivityTime < oldTime) {
21070                             app.kill("empty for "
21071                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21072                                     / 1000) + "s", true);
21073                         } else {
21074                             numEmpty++;
21075                             if (numEmpty > emptyProcessLimit) {
21076                                 app.kill("empty #" + numEmpty, true);
21077                             }
21078                         }
21079                         break;
21080                     default:
21081                         mNumNonCachedProcs++;
21082                         break;
21083                 }
21084
21085                 if (app.isolated && app.services.size() <= 0) {
21086                     // If this is an isolated process, and there are no
21087                     // services running in it, then the process is no longer
21088                     // needed.  We agressively kill these because we can by
21089                     // definition not re-use the same process again, and it is
21090                     // good to avoid having whatever code was running in them
21091                     // left sitting around after no longer needed.
21092                     app.kill("isolated not needed", true);
21093                 } else {
21094                     // Keeping this process, update its uid.
21095                     final UidRecord uidRec = app.uidRecord;
21096                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
21097                         uidRec.curProcState = app.curProcState;
21098                     }
21099                 }
21100
21101                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21102                         && !app.killedByAm) {
21103                     numTrimming++;
21104                 }
21105             }
21106         }
21107
21108         mNumServiceProcs = mNewNumServiceProcs;
21109
21110         // Now determine the memory trimming level of background processes.
21111         // Unfortunately we need to start at the back of the list to do this
21112         // properly.  We only do this if the number of background apps we
21113         // are managing to keep around is less than half the maximum we desire;
21114         // if we are keeping a good number around, we'll let them use whatever
21115         // memory they want.
21116         final int numCachedAndEmpty = numCached + numEmpty;
21117         int memFactor;
21118         if (numCached <= ProcessList.TRIM_CACHED_APPS
21119                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21120             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21121                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21122             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21123                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21124             } else {
21125                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21126             }
21127         } else {
21128             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21129         }
21130         // We always allow the memory level to go up (better).  We only allow it to go
21131         // down if we are in a state where that is allowed, *and* the total number of processes
21132         // has gone down since last time.
21133         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21134                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21135                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21136         if (memFactor > mLastMemoryLevel) {
21137             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21138                 memFactor = mLastMemoryLevel;
21139                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21140             }
21141         }
21142         if (memFactor != mLastMemoryLevel) {
21143             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21144         }
21145         mLastMemoryLevel = memFactor;
21146         mLastNumProcesses = mLruProcesses.size();
21147         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21148         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21149         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21150             if (mLowRamStartTime == 0) {
21151                 mLowRamStartTime = now;
21152             }
21153             int step = 0;
21154             int fgTrimLevel;
21155             switch (memFactor) {
21156                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21157                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21158                     break;
21159                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21160                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21161                     break;
21162                 default:
21163                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21164                     break;
21165             }
21166             int factor = numTrimming/3;
21167             int minFactor = 2;
21168             if (mHomeProcess != null) minFactor++;
21169             if (mPreviousProcess != null) minFactor++;
21170             if (factor < minFactor) factor = minFactor;
21171             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21172             for (int i=N-1; i>=0; i--) {
21173                 ProcessRecord app = mLruProcesses.get(i);
21174                 if (app == null) {
21175                     continue;
21176                 }
21177                 if (allChanged || app.procStateChanged) {
21178                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21179                     app.procStateChanged = false;
21180                 }
21181                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21182                         && !app.killedByAm) {
21183                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21184                         try {
21185                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21186                                     "Trimming memory of " + app.processName + " to " + curLevel);
21187                             app.thread.scheduleTrimMemory(curLevel);
21188                         } catch (RemoteException e) {
21189                         }
21190                         if (false) {
21191                             // For now we won't do this; our memory trimming seems
21192                             // to be good enough at this point that destroying
21193                             // activities causes more harm than good.
21194                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21195                                     && app != mHomeProcess && app != mPreviousProcess) {
21196                                 // Need to do this on its own message because the stack may not
21197                                 // be in a consistent state at this point.
21198                                 // For these apps we will also finish their activities
21199                                 // to help them free memory.
21200                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21201                             }
21202                         }
21203                     }
21204                     app.trimMemoryLevel = curLevel;
21205                     step++;
21206                     if (step >= factor) {
21207                         step = 0;
21208                         switch (curLevel) {
21209                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21210                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21211                                 break;
21212                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21213                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21214                                 break;
21215                         }
21216                     }
21217                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21218                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21219                             && app.thread != null) {
21220                         try {
21221                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21222                                     "Trimming memory of heavy-weight " + app.processName
21223                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21224                             app.thread.scheduleTrimMemory(
21225                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21226                         } catch (RemoteException e) {
21227                         }
21228                     }
21229                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21230                 } else {
21231                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21232                             || app.systemNoUi) && app.pendingUiClean) {
21233                         // If this application is now in the background and it
21234                         // had done UI, then give it the special trim level to
21235                         // have it free UI resources.
21236                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21237                         if (app.trimMemoryLevel < level && app.thread != null) {
21238                             try {
21239                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21240                                         "Trimming memory of bg-ui " + app.processName
21241                                         + " to " + level);
21242                                 app.thread.scheduleTrimMemory(level);
21243                             } catch (RemoteException e) {
21244                             }
21245                         }
21246                         app.pendingUiClean = false;
21247                     }
21248                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21249                         try {
21250                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21251                                     "Trimming memory of fg " + app.processName
21252                                     + " to " + fgTrimLevel);
21253                             app.thread.scheduleTrimMemory(fgTrimLevel);
21254                         } catch (RemoteException e) {
21255                         }
21256                     }
21257                     app.trimMemoryLevel = fgTrimLevel;
21258                 }
21259             }
21260         } else {
21261             if (mLowRamStartTime != 0) {
21262                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21263                 mLowRamStartTime = 0;
21264             }
21265             for (int i=N-1; i>=0; i--) {
21266                 ProcessRecord app = mLruProcesses.get(i);
21267                 if (allChanged || app.procStateChanged) {
21268                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21269                     app.procStateChanged = false;
21270                 }
21271                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21272                         || app.systemNoUi) && app.pendingUiClean) {
21273                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21274                             && app.thread != null) {
21275                         try {
21276                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21277                                     "Trimming memory of ui hidden " + app.processName
21278                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21279                             app.thread.scheduleTrimMemory(
21280                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21281                         } catch (RemoteException e) {
21282                         }
21283                     }
21284                     app.pendingUiClean = false;
21285                 }
21286                 app.trimMemoryLevel = 0;
21287             }
21288         }
21289
21290         if (mAlwaysFinishActivities) {
21291             // Need to do this on its own message because the stack may not
21292             // be in a consistent state at this point.
21293             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21294         }
21295
21296         if (allChanged) {
21297             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21298         }
21299
21300         // Update from any uid changes.
21301         for (int i=mActiveUids.size()-1; i>=0; i--) {
21302             final UidRecord uidRec = mActiveUids.valueAt(i);
21303             int uidChange = UidRecord.CHANGE_PROCSTATE;
21304             if (uidRec.setProcState != uidRec.curProcState) {
21305                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21306                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21307                         + " to " + uidRec.curProcState);
21308                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21309                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21310                         uidRec.lastBackgroundTime = nowElapsed;
21311                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21312                             // Note: the background settle time is in elapsed realtime, while
21313                             // the handler time base is uptime.  All this means is that we may
21314                             // stop background uids later than we had intended, but that only
21315                             // happens because the device was sleeping so we are okay anyway.
21316                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21317                         }
21318                     }
21319                 } else {
21320                     if (uidRec.idle) {
21321                         uidChange = UidRecord.CHANGE_ACTIVE;
21322                         uidRec.idle = false;
21323                     }
21324                     uidRec.lastBackgroundTime = 0;
21325                 }
21326                 uidRec.setProcState = uidRec.curProcState;
21327                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21328                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21329             }
21330         }
21331
21332         if (mProcessStats.shouldWriteNowLocked(now)) {
21333             mHandler.post(new Runnable() {
21334                 @Override public void run() {
21335                     synchronized (ActivityManagerService.this) {
21336                         mProcessStats.writeStateAsyncLocked();
21337                     }
21338                 }
21339             });
21340         }
21341
21342         if (DEBUG_OOM_ADJ) {
21343             final long duration = SystemClock.uptimeMillis() - now;
21344             if (false) {
21345                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21346                         new RuntimeException("here").fillInStackTrace());
21347             } else {
21348                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21349             }
21350         }
21351     }
21352
21353     final void idleUids() {
21354         synchronized (this) {
21355             final long nowElapsed = SystemClock.elapsedRealtime();
21356             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21357             long nextTime = 0;
21358             for (int i=mActiveUids.size()-1; i>=0; i--) {
21359                 final UidRecord uidRec = mActiveUids.valueAt(i);
21360                 final long bgTime = uidRec.lastBackgroundTime;
21361                 if (bgTime > 0 && !uidRec.idle) {
21362                     if (bgTime <= maxBgTime) {
21363                         uidRec.idle = true;
21364                         doStopUidLocked(uidRec.uid, uidRec);
21365                     } else {
21366                         if (nextTime == 0 || nextTime > bgTime) {
21367                             nextTime = bgTime;
21368                         }
21369                     }
21370                 }
21371             }
21372             if (nextTime > 0) {
21373                 mHandler.removeMessages(IDLE_UIDS_MSG);
21374                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21375                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21376             }
21377         }
21378     }
21379
21380     final void runInBackgroundDisabled(int uid) {
21381         synchronized (this) {
21382             UidRecord uidRec = mActiveUids.get(uid);
21383             if (uidRec != null) {
21384                 // This uid is actually running...  should it be considered background now?
21385                 if (uidRec.idle) {
21386                     doStopUidLocked(uidRec.uid, uidRec);
21387                 }
21388             } else {
21389                 // This uid isn't actually running...  still send a report about it being "stopped".
21390                 doStopUidLocked(uid, null);
21391             }
21392         }
21393     }
21394
21395     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21396         mServices.stopInBackgroundLocked(uid);
21397         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21398     }
21399
21400     final void trimApplications() {
21401         synchronized (this) {
21402             int i;
21403
21404             // First remove any unused application processes whose package
21405             // has been removed.
21406             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21407                 final ProcessRecord app = mRemovedProcesses.get(i);
21408                 if (app.activities.size() == 0
21409                         && app.curReceiver == null && app.services.size() == 0) {
21410                     Slog.i(
21411                         TAG, "Exiting empty application process "
21412                         + app.toShortString() + " ("
21413                         + (app.thread != null ? app.thread.asBinder() : null)
21414                         + ")\n");
21415                     if (app.pid > 0 && app.pid != MY_PID) {
21416                         app.kill("empty", false);
21417                     } else {
21418                         try {
21419                             app.thread.scheduleExit();
21420                         } catch (Exception e) {
21421                             // Ignore exceptions.
21422                         }
21423                     }
21424                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21425                     mRemovedProcesses.remove(i);
21426
21427                     if (app.persistent) {
21428                         addAppLocked(app.info, false, null /* ABI override */);
21429                     }
21430                 }
21431             }
21432
21433             // Now update the oom adj for all processes.
21434             updateOomAdjLocked();
21435         }
21436     }
21437
21438     /** This method sends the specified signal to each of the persistent apps */
21439     public void signalPersistentProcesses(int sig) throws RemoteException {
21440         if (sig != Process.SIGNAL_USR1) {
21441             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21442         }
21443
21444         synchronized (this) {
21445             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21446                     != PackageManager.PERMISSION_GRANTED) {
21447                 throw new SecurityException("Requires permission "
21448                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21449             }
21450
21451             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21452                 ProcessRecord r = mLruProcesses.get(i);
21453                 if (r.thread != null && r.persistent) {
21454                     Process.sendSignal(r.pid, sig);
21455                 }
21456             }
21457         }
21458     }
21459
21460     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21461         if (proc == null || proc == mProfileProc) {
21462             proc = mProfileProc;
21463             profileType = mProfileType;
21464             clearProfilerLocked();
21465         }
21466         if (proc == null) {
21467             return;
21468         }
21469         try {
21470             proc.thread.profilerControl(false, null, profileType);
21471         } catch (RemoteException e) {
21472             throw new IllegalStateException("Process disappeared");
21473         }
21474     }
21475
21476     private void clearProfilerLocked() {
21477         if (mProfileFd != null) {
21478             try {
21479                 mProfileFd.close();
21480             } catch (IOException e) {
21481             }
21482         }
21483         mProfileApp = null;
21484         mProfileProc = null;
21485         mProfileFile = null;
21486         mProfileType = 0;
21487         mAutoStopProfiler = false;
21488         mSamplingInterval = 0;
21489     }
21490
21491     public boolean profileControl(String process, int userId, boolean start,
21492             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21493
21494         try {
21495             synchronized (this) {
21496                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21497                 // its own permission.
21498                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21499                         != PackageManager.PERMISSION_GRANTED) {
21500                     throw new SecurityException("Requires permission "
21501                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21502                 }
21503
21504                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21505                     throw new IllegalArgumentException("null profile info or fd");
21506                 }
21507
21508                 ProcessRecord proc = null;
21509                 if (process != null) {
21510                     proc = findProcessLocked(process, userId, "profileControl");
21511                 }
21512
21513                 if (start && (proc == null || proc.thread == null)) {
21514                     throw new IllegalArgumentException("Unknown process: " + process);
21515                 }
21516
21517                 if (start) {
21518                     stopProfilerLocked(null, 0);
21519                     setProfileApp(proc.info, proc.processName, profilerInfo);
21520                     mProfileProc = proc;
21521                     mProfileType = profileType;
21522                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21523                     try {
21524                         fd = fd.dup();
21525                     } catch (IOException e) {
21526                         fd = null;
21527                     }
21528                     profilerInfo.profileFd = fd;
21529                     proc.thread.profilerControl(start, profilerInfo, profileType);
21530                     fd = null;
21531                     mProfileFd = null;
21532                 } else {
21533                     stopProfilerLocked(proc, profileType);
21534                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21535                         try {
21536                             profilerInfo.profileFd.close();
21537                         } catch (IOException e) {
21538                         }
21539                     }
21540                 }
21541
21542                 return true;
21543             }
21544         } catch (RemoteException e) {
21545             throw new IllegalStateException("Process disappeared");
21546         } finally {
21547             if (profilerInfo != null && profilerInfo.profileFd != null) {
21548                 try {
21549                     profilerInfo.profileFd.close();
21550                 } catch (IOException e) {
21551                 }
21552             }
21553         }
21554     }
21555
21556     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21557         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21558                 userId, true, ALLOW_FULL_ONLY, callName, null);
21559         ProcessRecord proc = null;
21560         try {
21561             int pid = Integer.parseInt(process);
21562             synchronized (mPidsSelfLocked) {
21563                 proc = mPidsSelfLocked.get(pid);
21564             }
21565         } catch (NumberFormatException e) {
21566         }
21567
21568         if (proc == null) {
21569             ArrayMap<String, SparseArray<ProcessRecord>> all
21570                     = mProcessNames.getMap();
21571             SparseArray<ProcessRecord> procs = all.get(process);
21572             if (procs != null && procs.size() > 0) {
21573                 proc = procs.valueAt(0);
21574                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21575                     for (int i=1; i<procs.size(); i++) {
21576                         ProcessRecord thisProc = procs.valueAt(i);
21577                         if (thisProc.userId == userId) {
21578                             proc = thisProc;
21579                             break;
21580                         }
21581                     }
21582                 }
21583             }
21584         }
21585
21586         return proc;
21587     }
21588
21589     public boolean dumpHeap(String process, int userId, boolean managed,
21590             String path, ParcelFileDescriptor fd) throws RemoteException {
21591
21592         try {
21593             synchronized (this) {
21594                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21595                 // its own permission (same as profileControl).
21596                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21597                         != PackageManager.PERMISSION_GRANTED) {
21598                     throw new SecurityException("Requires permission "
21599                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21600                 }
21601
21602                 if (fd == null) {
21603                     throw new IllegalArgumentException("null fd");
21604                 }
21605
21606                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21607                 if (proc == null || proc.thread == null) {
21608                     throw new IllegalArgumentException("Unknown process: " + process);
21609                 }
21610
21611                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21612                 if (!isDebuggable) {
21613                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21614                         throw new SecurityException("Process not debuggable: " + proc);
21615                     }
21616                 }
21617
21618                 proc.thread.dumpHeap(managed, path, fd);
21619                 fd = null;
21620                 return true;
21621             }
21622         } catch (RemoteException e) {
21623             throw new IllegalStateException("Process disappeared");
21624         } finally {
21625             if (fd != null) {
21626                 try {
21627                     fd.close();
21628                 } catch (IOException e) {
21629                 }
21630             }
21631         }
21632     }
21633
21634     @Override
21635     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21636             String reportPackage) {
21637         if (processName != null) {
21638             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21639                     "setDumpHeapDebugLimit()");
21640         } else {
21641             synchronized (mPidsSelfLocked) {
21642                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21643                 if (proc == null) {
21644                     throw new SecurityException("No process found for calling pid "
21645                             + Binder.getCallingPid());
21646                 }
21647                 if (!Build.IS_DEBUGGABLE
21648                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21649                     throw new SecurityException("Not running a debuggable build");
21650                 }
21651                 processName = proc.processName;
21652                 uid = proc.uid;
21653                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21654                     throw new SecurityException("Package " + reportPackage + " is not running in "
21655                             + proc);
21656                 }
21657             }
21658         }
21659         synchronized (this) {
21660             if (maxMemSize > 0) {
21661                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21662             } else {
21663                 if (uid != 0) {
21664                     mMemWatchProcesses.remove(processName, uid);
21665                 } else {
21666                     mMemWatchProcesses.getMap().remove(processName);
21667                 }
21668             }
21669         }
21670     }
21671
21672     @Override
21673     public void dumpHeapFinished(String path) {
21674         synchronized (this) {
21675             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21676                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21677                         + " does not match last pid " + mMemWatchDumpPid);
21678                 return;
21679             }
21680             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21681                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21682                         + " does not match last path " + mMemWatchDumpFile);
21683                 return;
21684             }
21685             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21686             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21687         }
21688     }
21689
21690     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21691     public void monitor() {
21692         synchronized (this) { }
21693     }
21694
21695     void onCoreSettingsChange(Bundle settings) {
21696         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21697             ProcessRecord processRecord = mLruProcesses.get(i);
21698             try {
21699                 if (processRecord.thread != null) {
21700                     processRecord.thread.setCoreSettings(settings);
21701                 }
21702             } catch (RemoteException re) {
21703                 /* ignore */
21704             }
21705         }
21706     }
21707
21708     // Multi-user methods
21709
21710     /**
21711      * Start user, if its not already running, but don't bring it to foreground.
21712      */
21713     @Override
21714     public boolean startUserInBackground(final int userId) {
21715         return mUserController.startUser(userId, /* foreground */ false);
21716     }
21717
21718     @Override
21719     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21720         return mUserController.unlockUser(userId, token, secret, listener);
21721     }
21722
21723     @Override
21724     public boolean switchUser(final int targetUserId) {
21725         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21726         UserInfo currentUserInfo;
21727         UserInfo targetUserInfo;
21728         synchronized (this) {
21729             int currentUserId = mUserController.getCurrentUserIdLocked();
21730             currentUserInfo = mUserController.getUserInfo(currentUserId);
21731             targetUserInfo = mUserController.getUserInfo(targetUserId);
21732             if (targetUserInfo == null) {
21733                 Slog.w(TAG, "No user info for user #" + targetUserId);
21734                 return false;
21735             }
21736             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21737                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21738                         + " when device is in demo mode");
21739                 return false;
21740             }
21741             if (!targetUserInfo.supportsSwitchTo()) {
21742                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21743                 return false;
21744             }
21745             if (targetUserInfo.isManagedProfile()) {
21746                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21747                 return false;
21748             }
21749             mUserController.setTargetUserIdLocked(targetUserId);
21750         }
21751         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21752         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21753         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21754         return true;
21755     }
21756
21757     void scheduleStartProfilesLocked() {
21758         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21759             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21760                     DateUtils.SECOND_IN_MILLIS);
21761         }
21762     }
21763
21764     @Override
21765     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21766         return mUserController.stopUser(userId, force, callback);
21767     }
21768
21769     @Override
21770     public UserInfo getCurrentUser() {
21771         return mUserController.getCurrentUser();
21772     }
21773
21774     @Override
21775     public boolean isUserRunning(int userId, int flags) {
21776         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21777                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21778                     != PackageManager.PERMISSION_GRANTED) {
21779             String msg = "Permission Denial: isUserRunning() from pid="
21780                     + Binder.getCallingPid()
21781                     + ", uid=" + Binder.getCallingUid()
21782                     + " requires " + INTERACT_ACROSS_USERS;
21783             Slog.w(TAG, msg);
21784             throw new SecurityException(msg);
21785         }
21786         synchronized (this) {
21787             return mUserController.isUserRunningLocked(userId, flags);
21788         }
21789     }
21790
21791     @Override
21792     public int[] getRunningUserIds() {
21793         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21794                 != PackageManager.PERMISSION_GRANTED) {
21795             String msg = "Permission Denial: isUserRunning() from pid="
21796                     + Binder.getCallingPid()
21797                     + ", uid=" + Binder.getCallingUid()
21798                     + " requires " + INTERACT_ACROSS_USERS;
21799             Slog.w(TAG, msg);
21800             throw new SecurityException(msg);
21801         }
21802         synchronized (this) {
21803             return mUserController.getStartedUserArrayLocked();
21804         }
21805     }
21806
21807     @Override
21808     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21809         mUserController.registerUserSwitchObserver(observer, name);
21810     }
21811
21812     @Override
21813     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21814         mUserController.unregisterUserSwitchObserver(observer);
21815     }
21816
21817     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21818         if (info == null) return null;
21819         ApplicationInfo newInfo = new ApplicationInfo(info);
21820         newInfo.initForUser(userId);
21821         return newInfo;
21822     }
21823
21824     public boolean isUserStopped(int userId) {
21825         synchronized (this) {
21826             return mUserController.getStartedUserStateLocked(userId) == null;
21827         }
21828     }
21829
21830     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21831         if (aInfo == null
21832                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21833             return aInfo;
21834         }
21835
21836         ActivityInfo info = new ActivityInfo(aInfo);
21837         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21838         return info;
21839     }
21840
21841     private boolean processSanityChecksLocked(ProcessRecord process) {
21842         if (process == null || process.thread == null) {
21843             return false;
21844         }
21845
21846         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21847         if (!isDebuggable) {
21848             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21849                 return false;
21850             }
21851         }
21852
21853         return true;
21854     }
21855
21856     public boolean startBinderTracking() throws RemoteException {
21857         synchronized (this) {
21858             mBinderTransactionTrackingEnabled = true;
21859             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21860             // permission (same as profileControl).
21861             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21862                     != PackageManager.PERMISSION_GRANTED) {
21863                 throw new SecurityException("Requires permission "
21864                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21865             }
21866
21867             for (int i = 0; i < mLruProcesses.size(); i++) {
21868                 ProcessRecord process = mLruProcesses.get(i);
21869                 if (!processSanityChecksLocked(process)) {
21870                     continue;
21871                 }
21872                 try {
21873                     process.thread.startBinderTracking();
21874                 } catch (RemoteException e) {
21875                     Log.v(TAG, "Process disappared");
21876                 }
21877             }
21878             return true;
21879         }
21880     }
21881
21882     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21883         try {
21884             synchronized (this) {
21885                 mBinderTransactionTrackingEnabled = false;
21886                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21887                 // permission (same as profileControl).
21888                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21889                         != PackageManager.PERMISSION_GRANTED) {
21890                     throw new SecurityException("Requires permission "
21891                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21892                 }
21893
21894                 if (fd == null) {
21895                     throw new IllegalArgumentException("null fd");
21896                 }
21897
21898                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21899                 pw.println("Binder transaction traces for all processes.\n");
21900                 for (ProcessRecord process : mLruProcesses) {
21901                     if (!processSanityChecksLocked(process)) {
21902                         continue;
21903                     }
21904
21905                     pw.println("Traces for process: " + process.processName);
21906                     pw.flush();
21907                     try {
21908                         TransferPipe tp = new TransferPipe();
21909                         try {
21910                             process.thread.stopBinderTrackingAndDump(
21911                                     tp.getWriteFd().getFileDescriptor());
21912                             tp.go(fd.getFileDescriptor());
21913                         } finally {
21914                             tp.kill();
21915                         }
21916                     } catch (IOException e) {
21917                         pw.println("Failure while dumping IPC traces from " + process +
21918                                 ".  Exception: " + e);
21919                         pw.flush();
21920                     } catch (RemoteException e) {
21921                         pw.println("Got a RemoteException while dumping IPC traces from " +
21922                                 process + ".  Exception: " + e);
21923                         pw.flush();
21924                     }
21925                 }
21926                 fd = null;
21927                 return true;
21928             }
21929         } finally {
21930             if (fd != null) {
21931                 try {
21932                     fd.close();
21933                 } catch (IOException e) {
21934                 }
21935             }
21936         }
21937     }
21938
21939     private final class LocalService extends ActivityManagerInternal {
21940         @Override
21941         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21942                 int targetUserId) {
21943             synchronized (ActivityManagerService.this) {
21944                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21945                         targetPkg, intent, null, targetUserId);
21946             }
21947         }
21948
21949         @Override
21950         public String checkContentProviderAccess(String authority, int userId) {
21951             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21952         }
21953
21954         @Override
21955         public void onWakefulnessChanged(int wakefulness) {
21956             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21957         }
21958
21959         @Override
21960         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21961                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21962             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21963                     processName, abiOverride, uid, crashHandler);
21964         }
21965
21966         @Override
21967         public SleepToken acquireSleepToken(String tag) {
21968             Preconditions.checkNotNull(tag);
21969
21970             synchronized (ActivityManagerService.this) {
21971                 SleepTokenImpl token = new SleepTokenImpl(tag);
21972                 mSleepTokens.add(token);
21973                 updateSleepIfNeededLocked();
21974                 return token;
21975             }
21976         }
21977
21978         @Override
21979         public ComponentName getHomeActivityForUser(int userId) {
21980             synchronized (ActivityManagerService.this) {
21981                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21982                 return homeActivity == null ? null : homeActivity.realActivity;
21983             }
21984         }
21985
21986         @Override
21987         public void onUserRemoved(int userId) {
21988             synchronized (ActivityManagerService.this) {
21989                 ActivityManagerService.this.onUserStoppedLocked(userId);
21990             }
21991         }
21992
21993         @Override
21994         public void onLocalVoiceInteractionStarted(IBinder activity,
21995                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21996             synchronized (ActivityManagerService.this) {
21997                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21998                         voiceSession, voiceInteractor);
21999             }
22000         }
22001
22002         @Override
22003         public void notifyStartingWindowDrawn() {
22004             synchronized (ActivityManagerService.this) {
22005                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22006             }
22007         }
22008
22009         @Override
22010         public void notifyAppTransitionStarting(int reason) {
22011             synchronized (ActivityManagerService.this) {
22012                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22013             }
22014         }
22015
22016         @Override
22017         public void notifyAppTransitionFinished() {
22018             synchronized (ActivityManagerService.this) {
22019                 mStackSupervisor.notifyAppTransitionDone();
22020             }
22021         }
22022
22023         @Override
22024         public void notifyAppTransitionCancelled() {
22025             synchronized (ActivityManagerService.this) {
22026                 mStackSupervisor.notifyAppTransitionDone();
22027             }
22028         }
22029
22030         @Override
22031         public List<IBinder> getTopVisibleActivities() {
22032             synchronized (ActivityManagerService.this) {
22033                 return mStackSupervisor.getTopVisibleActivities();
22034             }
22035         }
22036
22037         @Override
22038         public void notifyDockedStackMinimizedChanged(boolean minimized) {
22039             synchronized (ActivityManagerService.this) {
22040                 mStackSupervisor.setDockedStackMinimized(minimized);
22041             }
22042         }
22043
22044         @Override
22045         public void killForegroundAppsForUser(int userHandle) {
22046             synchronized (ActivityManagerService.this) {
22047                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22048                 final int NP = mProcessNames.getMap().size();
22049                 for (int ip = 0; ip < NP; ip++) {
22050                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22051                     final int NA = apps.size();
22052                     for (int ia = 0; ia < NA; ia++) {
22053                         final ProcessRecord app = apps.valueAt(ia);
22054                         if (app.persistent) {
22055                             // We don't kill persistent processes.
22056                             continue;
22057                         }
22058                         if (app.removed) {
22059                             procs.add(app);
22060                         } else if (app.userId == userHandle && app.foregroundActivities) {
22061                             app.removed = true;
22062                             procs.add(app);
22063                         }
22064                     }
22065                 }
22066
22067                 final int N = procs.size();
22068                 for (int i = 0; i < N; i++) {
22069                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
22070                 }
22071             }
22072         }
22073
22074         @Override
22075         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22076             if (!(target instanceof PendingIntentRecord)) {
22077                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22078                 return;
22079             }
22080             ((PendingIntentRecord) target).setWhitelistDuration(duration);
22081         }
22082
22083         @Override
22084         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22085                 int userId) {
22086             Preconditions.checkNotNull(values, "Configuration must not be null");
22087             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22088             synchronized (ActivityManagerService.this) {
22089                 updateConfigurationLocked(values, null, false, true, userId,
22090                         false /* deferResume */);
22091             }
22092         }
22093
22094         @Override
22095         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22096                 Bundle bOptions) {
22097             Preconditions.checkNotNull(intents, "intents");
22098             final String[] resolvedTypes = new String[intents.length];
22099             for (int i = 0; i < intents.length; i++) {
22100                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22101             }
22102
22103             // UID of the package on user userId.
22104             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22105             // packageUid may not be initialized.
22106             int packageUid = 0;
22107             try {
22108                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22109                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22110             } catch (RemoteException e) {
22111                 // Shouldn't happen.
22112             }
22113
22114             synchronized (ActivityManagerService.this) {
22115                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22116                         /*resultTo*/ null, bOptions, userId);
22117             }
22118         }
22119
22120         @Override
22121         public int getUidProcessState(int uid) {
22122             return getUidState(uid);
22123         }
22124     }
22125
22126     private final class SleepTokenImpl extends SleepToken {
22127         private final String mTag;
22128         private final long mAcquireTime;
22129
22130         public SleepTokenImpl(String tag) {
22131             mTag = tag;
22132             mAcquireTime = SystemClock.uptimeMillis();
22133         }
22134
22135         @Override
22136         public void release() {
22137             synchronized (ActivityManagerService.this) {
22138                 if (mSleepTokens.remove(this)) {
22139                     updateSleepIfNeededLocked();
22140                 }
22141             }
22142         }
22143
22144         @Override
22145         public String toString() {
22146             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22147         }
22148     }
22149
22150     /**
22151      * An implementation of IAppTask, that allows an app to manage its own tasks via
22152      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22153      * only the process that calls getAppTasks() can call the AppTask methods.
22154      */
22155     class AppTaskImpl extends IAppTask.Stub {
22156         private int mTaskId;
22157         private int mCallingUid;
22158
22159         public AppTaskImpl(int taskId, int callingUid) {
22160             mTaskId = taskId;
22161             mCallingUid = callingUid;
22162         }
22163
22164         private void checkCaller() {
22165             if (mCallingUid != Binder.getCallingUid()) {
22166                 throw new SecurityException("Caller " + mCallingUid
22167                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22168             }
22169         }
22170
22171         @Override
22172         public void finishAndRemoveTask() {
22173             checkCaller();
22174
22175             synchronized (ActivityManagerService.this) {
22176                 long origId = Binder.clearCallingIdentity();
22177                 try {
22178                     // We remove the task from recents to preserve backwards
22179                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22180                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22181                     }
22182                 } finally {
22183                     Binder.restoreCallingIdentity(origId);
22184                 }
22185             }
22186         }
22187
22188         @Override
22189         public ActivityManager.RecentTaskInfo getTaskInfo() {
22190             checkCaller();
22191
22192             synchronized (ActivityManagerService.this) {
22193                 long origId = Binder.clearCallingIdentity();
22194                 try {
22195                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22196                     if (tr == null) {
22197                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22198                     }
22199                     return createRecentTaskInfoFromTaskRecord(tr);
22200                 } finally {
22201                     Binder.restoreCallingIdentity(origId);
22202                 }
22203             }
22204         }
22205
22206         @Override
22207         public void moveToFront() {
22208             checkCaller();
22209             // Will bring task to front if it already has a root activity.
22210             final long origId = Binder.clearCallingIdentity();
22211             try {
22212                 synchronized (this) {
22213                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22214                 }
22215             } finally {
22216                 Binder.restoreCallingIdentity(origId);
22217             }
22218         }
22219
22220         @Override
22221         public int startActivity(IBinder whoThread, String callingPackage,
22222                 Intent intent, String resolvedType, Bundle bOptions) {
22223             checkCaller();
22224
22225             int callingUser = UserHandle.getCallingUserId();
22226             TaskRecord tr;
22227             IApplicationThread appThread;
22228             synchronized (ActivityManagerService.this) {
22229                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22230                 if (tr == null) {
22231                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22232                 }
22233                 appThread = ApplicationThreadNative.asInterface(whoThread);
22234                 if (appThread == null) {
22235                     throw new IllegalArgumentException("Bad app thread " + appThread);
22236                 }
22237             }
22238             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22239                     resolvedType, null, null, null, null, 0, 0, null, null,
22240                     null, bOptions, false, callingUser, null, tr);
22241         }
22242
22243         @Override
22244         public void setExcludeFromRecents(boolean exclude) {
22245             checkCaller();
22246
22247             synchronized (ActivityManagerService.this) {
22248                 long origId = Binder.clearCallingIdentity();
22249                 try {
22250                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22251                     if (tr == null) {
22252                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22253                     }
22254                     Intent intent = tr.getBaseIntent();
22255                     if (exclude) {
22256                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22257                     } else {
22258                         intent.setFlags(intent.getFlags()
22259                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22260                     }
22261                 } finally {
22262                     Binder.restoreCallingIdentity(origId);
22263                 }
22264             }
22265         }
22266     }
22267
22268     /**
22269      * Kill processes for the user with id userId and that depend on the package named packageName
22270      */
22271     @Override
22272     public void killPackageDependents(String packageName, int userId) {
22273         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22274         if (packageName == null) {
22275             throw new NullPointerException(
22276                     "Cannot kill the dependents of a package without its name.");
22277         }
22278
22279         long callingId = Binder.clearCallingIdentity();
22280         IPackageManager pm = AppGlobals.getPackageManager();
22281         int pkgUid = -1;
22282         try {
22283             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22284         } catch (RemoteException e) {
22285         }
22286         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22287             throw new IllegalArgumentException(
22288                     "Cannot kill dependents of non-existing package " + packageName);
22289         }
22290         try {
22291             synchronized(this) {
22292                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22293                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22294                         "dep: " + packageName);
22295             }
22296         } finally {
22297             Binder.restoreCallingIdentity(callingId);
22298         }
22299     }
22300
22301     @Override
22302     public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22303         final int userId = intent.getCreatorUserHandle().getIdentifier();
22304         if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22305             return false;
22306         }
22307         IIntentSender target = intent.getTarget();
22308         if (!(target instanceof PendingIntentRecord)) {
22309             return false;
22310         }
22311         final PendingIntentRecord record = (PendingIntentRecord) target;
22312         final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22313                 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22314         // For direct boot aware activities, they can be shown without triggering a work challenge
22315         // before the profile user is unlocked.
22316         return rInfo != null && rInfo.activityInfo != null;
22317     }
22318 }