OSDN Git Service

Fix the documentation for SecurityLog.SecurityEvent.getData().
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
60
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
64
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
223
224 import java.io.File;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
249
250 import dalvik.system.VMRuntime;
251
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
254
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374 public final class ActivityManagerService extends ActivityManagerNative
375         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386     private static final String TAG_LRU = TAG + POSTFIX_LRU;
387     private static final String TAG_MU = TAG + POSTFIX_MU;
388     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389     private static final String TAG_POWER = TAG + POSTFIX_POWER;
390     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393     private static final String TAG_PSS = TAG + POSTFIX_PSS;
394     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396     private static final String TAG_STACK = TAG + POSTFIX_STACK;
397     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404     // here so that while the job scheduler can depend on AMS, the other way around
405     // need not be the case.
406     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408     /** Control over CPU and battery monitoring */
409     // write battery stats every 30 minutes.
410     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411     static final boolean MONITOR_CPU_USAGE = true;
412     // don't sample cpu less than every 5 seconds.
413     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414     // wait possibly forever for next cpu sample.
415     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416     static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418     // The flags that are set for all calls we make to the package manager.
419     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425     // Amount of time after a call to stopAppSwitches() during which we will
426     // prevent further untrusted switches from happening.
427     static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429     // How long we wait for a launched process to attach to the activity manager
430     // before we decide it's never going to come up for real.
431     static final int PROC_START_TIMEOUT = 10*1000;
432     // How long we wait for an attached process to publish its content providers
433     // before we decide it must be hung.
434     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436     // How long we will retain processes hosting content providers in the "last activity"
437     // state before allowing them to drop down to the regular cached LRU list.  This is
438     // to avoid thrashing of provider processes under low memory situations.
439     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441     // How long we wait for a launched process to attach to the activity manager
442     // before we decide it's never going to come up for real, when the process was
443     // started with a wrapper for instrumentation (such as Valgrind) because it
444     // could take much longer than usual.
445     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447     // How long to wait after going idle before forcing apps to GC.
448     static final int GC_TIMEOUT = 5*1000;
449
450     // The minimum amount of time between successive GC requests for a process.
451     static final int GC_MIN_INTERVAL = 60*1000;
452
453     // The minimum amount of time between successive PSS requests for a process.
454     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456     // The minimum amount of time between successive PSS requests for a process
457     // when the request is due to the memory state being lowered.
458     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460     // The rate at which we check for apps using excessive power -- 15 mins.
461     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463     // The minimum sample duration we will allow before deciding we have
464     // enough data on wake locks to start killing things.
465     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467     // The minimum sample duration we will allow before deciding we have
468     // enough data on CPU usage to start killing things.
469     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471     // How long we allow a receiver to run before giving up on it.
472     static final int BROADCAST_FG_TIMEOUT = 10*1000;
473     static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475     // How long we wait until we timeout on key dispatching.
476     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478     // How long we wait until we timeout on key dispatching during instrumentation.
479     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481     // This is the amount of time an app needs to be running a foreground service before
482     // we will consider it to be doing interaction for usage stats.
483     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485     // Maximum amount of time we will allow to elapse before re-reporting usage stats
486     // interaction with foreground processes.
487     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489     // This is the amount of time we allow an app to settle after it goes into the background,
490     // before we start restricting what it can do.
491     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493     // How long to wait in getAssistContextExtras for the activity and foreground services
494     // to respond with the result.
495     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497     // How long top wait when going through the modern assist (which doesn't need to block
498     // on getting this result before starting to launch its UI).
499     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501     // Maximum number of persisted Uri grants a package is allowed
502     static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504     static final int MY_PID = Process.myPid();
505
506     static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508     // How many bytes to write into the dropbox log before truncating
509     static final int DROPBOX_MAX_SIZE = 192 * 1024;
510     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511     // as one line, but close enough for now.
512     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514     // Access modes for handleIncomingUser.
515     static final int ALLOW_NON_FULL = 0;
516     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517     static final int ALLOW_FULL_ONLY = 2;
518
519     // Delay in notifying task stack change listeners (in millis)
520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522     // Necessary ApplicationInfo flags to mark an app as persistent
523     private static final int PERSISTENT_MASK =
524             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526     // Intent sent when remote bugreport collection has been completed
527     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530     // Delay to disable app launch boost
531     static final int APP_BOOST_MESSAGE_DELAY = 3000;
532     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533     static final int APP_BOOST_TIMEOUT = 2500;
534
535     // Used to indicate that a task is removed it should also be removed from recents.
536     private static final boolean REMOVE_FROM_RECENTS = true;
537     // Used to indicate that an app transition should be animated.
538     static final boolean ANIMATE = true;
539
540     // Determines whether to take full screen screenshots
541     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544     private static native int nativeMigrateToBoost();
545     private static native int nativeMigrateFromBoost();
546     private boolean mIsBoosted = false;
547     private long mBoostStartTime = 0;
548
549     /** All system services */
550     SystemServiceManager mSystemServiceManager;
551
552     private Installer mInstaller;
553
554     /** Run all ActivityStacks through this */
555     final ActivityStackSupervisor mStackSupervisor;
556
557     final ActivityStarter mActivityStarter;
558
559     /** Task stack change listeners. */
560     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561             new RemoteCallbackList<ITaskStackListener>();
562
563     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565     public IntentFirewall mIntentFirewall;
566
567     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568     // default actuion automatically.  Important for devices without direct input
569     // devices.
570     private boolean mShowDialogs = true;
571     private boolean mInVrMode = false;
572
573     // Whether we should use SCHED_FIFO for UI and RenderThreads.
574     private boolean mUseFifoUiScheduling = false;
575
576     BroadcastQueue mFgBroadcastQueue;
577     BroadcastQueue mBgBroadcastQueue;
578     // Convenient for easy iteration over the queues. Foreground is first
579     // so that dispatch of foreground broadcasts gets precedence.
580     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582     BroadcastStats mLastBroadcastStats;
583     BroadcastStats mCurBroadcastStats;
584
585     BroadcastQueue broadcastQueueForIntent(Intent intent) {
586         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                 "Broadcast intent " + intent + " on "
589                 + (isFg ? "foreground" : "background") + " queue");
590         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591     }
592
593     /**
594      * Activity we have told the window manager to have key focus.
595      */
596     ActivityRecord mFocusedActivity = null;
597
598     /**
599      * User id of the last activity mFocusedActivity was set to.
600      */
601     private int mLastFocusedUserId;
602
603     /**
604      * If non-null, we are tracking the time the user spends in the currently focused app.
605      */
606     private AppTimeTracker mCurAppTimeTracker;
607
608     /**
609      * List of intents that were used to start the most recent tasks.
610      */
611     final RecentTasks mRecentTasks;
612
613     /**
614      * For addAppTask: cached of the last activity component that was added.
615      */
616     ComponentName mLastAddedTaskComponent;
617
618     /**
619      * For addAppTask: cached of the last activity uid that was added.
620      */
621     int mLastAddedTaskUid;
622
623     /**
624      * For addAppTask: cached of the last ActivityInfo that was added.
625      */
626     ActivityInfo mLastAddedTaskActivity;
627
628     /**
629      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630      */
631     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633     /**
634      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635      */
636     String mDeviceOwnerName;
637
638     final UserController mUserController;
639
640     final AppErrors mAppErrors;
641
642     boolean mDoingSetFocusedActivity;
643
644     public boolean canShowErrorDialogs() {
645         return mShowDialogs && !mSleeping && !mShuttingDown
646                 && mLockScreenShown != LOCK_SCREEN_SHOWN;
647     }
648
649     private static final class PriorityState {
650         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651         // the current thread is currently in. When it drops down to zero, we will no longer boost
652         // the thread's priority.
653         private int regionCounter = 0;
654
655         // The thread's previous priority before boosting.
656         private int prevPriority = Integer.MIN_VALUE;
657     }
658
659     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660         @Override protected PriorityState initialValue() {
661             return new PriorityState();
662         }
663     };
664
665     static void boostPriorityForLockedSection() {
666         int tid = Process.myTid();
667         int prevPriority = Process.getThreadPriority(tid);
668         PriorityState state = sThreadPriorityState.get();
669         if (state.regionCounter == 0 && prevPriority > -2) {
670             state.prevPriority = prevPriority;
671             Process.setThreadPriority(tid, -2);
672         }
673         state.regionCounter++;
674     }
675
676     static void resetPriorityAfterLockedSection() {
677         PriorityState state = sThreadPriorityState.get();
678         state.regionCounter--;
679         if (state.regionCounter == 0 && state.prevPriority > -2) {
680             Process.setThreadPriority(Process.myTid(), state.prevPriority);
681         }
682     }
683
684     public class PendingAssistExtras extends Binder implements Runnable {
685         public final ActivityRecord activity;
686         public final Bundle extras;
687         public final Intent intent;
688         public final String hint;
689         public final IResultReceiver receiver;
690         public final int userHandle;
691         public boolean haveResult = false;
692         public Bundle result = null;
693         public AssistStructure structure = null;
694         public AssistContent content = null;
695         public Bundle receiverExtras;
696
697         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699             activity = _activity;
700             extras = _extras;
701             intent = _intent;
702             hint = _hint;
703             receiver = _receiver;
704             receiverExtras = _receiverExtras;
705             userHandle = _userHandle;
706         }
707         @Override
708         public void run() {
709             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710             synchronized (this) {
711                 haveResult = true;
712                 notifyAll();
713             }
714             pendingAssistExtrasTimedOut(this);
715         }
716     }
717
718     final ArrayList<PendingAssistExtras> mPendingAssistExtras
719             = new ArrayList<PendingAssistExtras>();
720
721     /**
722      * Process management.
723      */
724     final ProcessList mProcessList = new ProcessList();
725
726     /**
727      * All of the applications we currently have running organized by name.
728      * The keys are strings of the application package name (as
729      * returned by the package manager), and the keys are ApplicationRecord
730      * objects.
731      */
732     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734     /**
735      * Tracking long-term execution of processes to look for abuse and other
736      * bad app behavior.
737      */
738     final ProcessStatsService mProcessStats;
739
740     /**
741      * The currently running isolated processes.
742      */
743     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745     /**
746      * Counter for assigning isolated process uids, to avoid frequently reusing the
747      * same ones.
748      */
749     int mNextIsolatedProcessUid = 0;
750
751     /**
752      * The currently running heavy-weight process, if any.
753      */
754     ProcessRecord mHeavyWeightProcess = null;
755
756     /**
757      * All of the processes we currently have running organized by pid.
758      * The keys are the pid running the application.
759      *
760      * <p>NOTE: This object is protected by its own lock, NOT the global
761      * activity manager lock!
762      */
763     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765     /**
766      * All of the processes that have been forced to be foreground.  The key
767      * is the pid of the caller who requested it (we hold a death
768      * link on it).
769      */
770     abstract class ForegroundToken implements IBinder.DeathRecipient {
771         int pid;
772         IBinder token;
773     }
774     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776     /**
777      * List of records for processes that someone had tried to start before the
778      * system was ready.  We don't start them at that point, but ensure they
779      * are started by the time booting is complete.
780      */
781     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783     /**
784      * List of persistent applications that are in the process
785      * of being started.
786      */
787     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789     /**
790      * Processes that are being forcibly torn down.
791      */
792     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794     /**
795      * List of running applications, sorted by recent usage.
796      * The first entry in the list is the least recently used.
797      */
798     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800     /**
801      * Where in mLruProcesses that the processes hosting activities start.
802      */
803     int mLruProcessActivityStart = 0;
804
805     /**
806      * Where in mLruProcesses that the processes hosting services start.
807      * This is after (lower index) than mLruProcessesActivityStart.
808      */
809     int mLruProcessServiceStart = 0;
810
811     /**
812      * List of processes that should gc as soon as things are idle.
813      */
814     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816     /**
817      * Processes we want to collect PSS data from.
818      */
819     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821     private boolean mBinderTransactionTrackingEnabled = false;
822
823     /**
824      * Last time we requested PSS data of all processes.
825      */
826     long mLastFullPssTime = SystemClock.uptimeMillis();
827
828     /**
829      * If set, the next time we collect PSS data we should do a full collection
830      * with data from native processes and the kernel.
831      */
832     boolean mFullPssPending = false;
833
834     /**
835      * This is the process holding what we currently consider to be
836      * the "home" activity.
837      */
838     ProcessRecord mHomeProcess;
839
840     /**
841      * This is the process holding the activity the user last visited that
842      * is in a different process from the one they are currently in.
843      */
844     ProcessRecord mPreviousProcess;
845
846     /**
847      * The time at which the previous process was last visible.
848      */
849     long mPreviousProcessVisibleTime;
850
851     /**
852      * Track all uids that have actively running processes.
853      */
854     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856     /**
857      * This is for verifying the UID report flow.
858      */
859     static final boolean VALIDATE_UID_STATES = true;
860     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862     /**
863      * Packages that the user has asked to have run in screen size
864      * compatibility mode instead of filling the screen.
865      */
866     final CompatModePackages mCompatModePackages;
867
868     /**
869      * Set of IntentSenderRecord objects that are currently active.
870      */
871     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874     /**
875      * Fingerprints (hashCode()) of stack traces that we've
876      * already logged DropBox entries for.  Guarded by itself.  If
877      * something (rogue user app) forces this over
878      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879      */
880     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883     /**
884      * Strict Mode background batched logging state.
885      *
886      * The string buffer is guarded by itself, and its lock is also
887      * used to determine if another batched write is already
888      * in-flight.
889      */
890     private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892     /**
893      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895      */
896     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898     /**
899      * Resolver for broadcast intents to registered receivers.
900      * Holds BroadcastFilter (subclass of IntentFilter).
901      */
902     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904         @Override
905         protected boolean allowFilterResult(
906                 BroadcastFilter filter, List<BroadcastFilter> dest) {
907             IBinder target = filter.receiverList.receiver.asBinder();
908             for (int i = dest.size() - 1; i >= 0; i--) {
909                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                     return false;
911                 }
912             }
913             return true;
914         }
915
916         @Override
917         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                     || userId == filter.owningUserId) {
920                 return super.newResult(filter, match, userId);
921             }
922             return null;
923         }
924
925         @Override
926         protected BroadcastFilter[] newArray(int size) {
927             return new BroadcastFilter[size];
928         }
929
930         @Override
931         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932             return packageName.equals(filter.packageName);
933         }
934     };
935
936     /**
937      * State of all active sticky broadcasts per user.  Keys are the action of the
938      * sticky Intent, values are an ArrayList of all broadcasted intents with
939      * that action (which should usually be one).  The SparseArray is keyed
940      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941      * for stickies that are sent to all users.
942      */
943     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946     final ActiveServices mServices;
947
948     final static class Association {
949         final int mSourceUid;
950         final String mSourceProcess;
951         final int mTargetUid;
952         final ComponentName mTargetComponent;
953         final String mTargetProcess;
954
955         int mCount;
956         long mTime;
957
958         int mNesting;
959         long mStartTime;
960
961         // states of the source process when the bind occurred.
962         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963         long mLastStateUptime;
964         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                 - ActivityManager.MIN_PROCESS_STATE+1];
966
967         Association(int sourceUid, String sourceProcess, int targetUid,
968                 ComponentName targetComponent, String targetProcess) {
969             mSourceUid = sourceUid;
970             mSourceProcess = sourceProcess;
971             mTargetUid = targetUid;
972             mTargetComponent = targetComponent;
973             mTargetProcess = targetProcess;
974         }
975     }
976
977     /**
978      * When service association tracking is enabled, this is all of the associations we
979      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980      * -> association data.
981      */
982     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983             mAssociations = new SparseArray<>();
984     boolean mTrackingAssociations;
985
986     /**
987      * Backup/restore process management
988      */
989     String mBackupAppName = null;
990     BackupRecord mBackupTarget = null;
991
992     final ProviderMap mProviderMap;
993
994     /**
995      * List of content providers who have clients waiting for them.  The
996      * application is currently being launched and the provider will be
997      * removed from this list once it is published.
998      */
999     final ArrayList<ContentProviderRecord> mLaunchingProviders
1000             = new ArrayList<ContentProviderRecord>();
1001
1002     /**
1003      * File storing persisted {@link #mGrantedUriPermissions}.
1004      */
1005     private final AtomicFile mGrantFile;
1006
1007     /** XML constants used in {@link #mGrantFile} */
1008     private static final String TAG_URI_GRANTS = "uri-grants";
1009     private static final String TAG_URI_GRANT = "uri-grant";
1010     private static final String ATTR_USER_HANDLE = "userHandle";
1011     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014     private static final String ATTR_TARGET_PKG = "targetPkg";
1015     private static final String ATTR_URI = "uri";
1016     private static final String ATTR_MODE_FLAGS = "modeFlags";
1017     private static final String ATTR_CREATED_TIME = "createdTime";
1018     private static final String ATTR_PREFIX = "prefix";
1019
1020     /**
1021      * Global set of specific {@link Uri} permissions that have been granted.
1022      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023      * to {@link UriPermission#uri} to {@link UriPermission}.
1024      */
1025     @GuardedBy("this")
1026     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029     public static class GrantUri {
1030         public final int sourceUserId;
1031         public final Uri uri;
1032         public boolean prefix;
1033
1034         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035             this.sourceUserId = sourceUserId;
1036             this.uri = uri;
1037             this.prefix = prefix;
1038         }
1039
1040         @Override
1041         public int hashCode() {
1042             int hashCode = 1;
1043             hashCode = 31 * hashCode + sourceUserId;
1044             hashCode = 31 * hashCode + uri.hashCode();
1045             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046             return hashCode;
1047         }
1048
1049         @Override
1050         public boolean equals(Object o) {
1051             if (o instanceof GrantUri) {
1052                 GrantUri other = (GrantUri) o;
1053                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                         && prefix == other.prefix;
1055             }
1056             return false;
1057         }
1058
1059         @Override
1060         public String toString() {
1061             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062             if (prefix) result += " [prefix]";
1063             return result;
1064         }
1065
1066         public String toSafeString() {
1067             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068             if (prefix) result += " [prefix]";
1069             return result;
1070         }
1071
1072         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                     ContentProvider.getUriWithoutUserId(uri), false);
1075         }
1076     }
1077
1078     CoreSettingsObserver mCoreSettingsObserver;
1079
1080     FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082     private final class FontScaleSettingObserver extends ContentObserver {
1083         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085         public FontScaleSettingObserver() {
1086             super(mHandler);
1087             ContentResolver resolver = mContext.getContentResolver();
1088             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089         }
1090
1091         @Override
1092         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093             if (mFontScaleUri.equals(uri)) {
1094                 updateFontScaleIfNeeded(userId);
1095             }
1096         }
1097     }
1098
1099     /**
1100      * Thread-local storage used to carry caller permissions over through
1101      * indirect content-provider access.
1102      */
1103     private class Identity {
1104         public final IBinder token;
1105         public final int pid;
1106         public final int uid;
1107
1108         Identity(IBinder _token, int _pid, int _uid) {
1109             token = _token;
1110             pid = _pid;
1111             uid = _uid;
1112         }
1113     }
1114
1115     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117     /**
1118      * All information we have collected about the runtime performance of
1119      * any user id that can impact battery performance.
1120      */
1121     final BatteryStatsService mBatteryStatsService;
1122
1123     /**
1124      * Information about component usage
1125      */
1126     UsageStatsManagerInternal mUsageStatsService;
1127
1128     /**
1129      * Access to DeviceIdleController service.
1130      */
1131     DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133     /**
1134      * Information about and control over application operations
1135      */
1136     final AppOpsService mAppOpsService;
1137
1138     /**
1139      * Current configuration information.  HistoryRecord objects are given
1140      * a reference to this object to indicate which configuration they are
1141      * currently running in, so this object must be kept immutable.
1142      */
1143     Configuration mConfiguration = new Configuration();
1144
1145     /**
1146      * Current sequencing integer of the configuration, for skipping old
1147      * configurations.
1148      */
1149     int mConfigurationSeq = 0;
1150
1151     boolean mSuppressResizeConfigChanges = false;
1152
1153     /**
1154      * Hardware-reported OpenGLES version.
1155      */
1156     final int GL_ES_VERSION;
1157
1158     /**
1159      * List of initialization arguments to pass to all processes when binding applications to them.
1160      * For example, references to the commonly used services.
1161      */
1162     HashMap<String, IBinder> mAppBindArgs;
1163     HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165     /**
1166      * Temporary to avoid allocations.  Protected by main lock.
1167      */
1168     final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170     /**
1171      * Used to control how we initialize the service.
1172      */
1173     ComponentName mTopComponent;
1174     String mTopAction = Intent.ACTION_MAIN;
1175     String mTopData;
1176
1177     volatile boolean mProcessesReady = false;
1178     volatile boolean mSystemReady = false;
1179     volatile boolean mOnBattery = false;
1180     volatile int mFactoryTest;
1181
1182     @GuardedBy("this") boolean mBooting = false;
1183     @GuardedBy("this") boolean mCallFinishBooting = false;
1184     @GuardedBy("this") boolean mBootAnimationComplete = false;
1185     @GuardedBy("this") boolean mLaunchWarningShown = false;
1186     @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188     Context mContext;
1189
1190     /**
1191      * The time at which we will allow normal application switches again,
1192      * after a call to {@link #stopAppSwitches()}.
1193      */
1194     long mAppSwitchesAllowedTime;
1195
1196     /**
1197      * This is set to true after the first switch after mAppSwitchesAllowedTime
1198      * is set; any switches after that will clear the time.
1199      */
1200     boolean mDidAppSwitch;
1201
1202     /**
1203      * Last time (in realtime) at which we checked for power usage.
1204      */
1205     long mLastPowerCheckRealtime;
1206
1207     /**
1208      * Last time (in uptime) at which we checked for power usage.
1209      */
1210     long mLastPowerCheckUptime;
1211
1212     /**
1213      * Set while we are wanting to sleep, to prevent any
1214      * activities from being started/resumed.
1215      */
1216     private boolean mSleeping = false;
1217
1218     /**
1219      * The process state used for processes that are running the top activities.
1220      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221      */
1222     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1223
1224     /**
1225      * Set while we are running a voice interaction.  This overrides
1226      * sleeping while it is active.
1227      */
1228     private IVoiceInteractionSession mRunningVoice;
1229
1230     /**
1231      * For some direct access we need to power manager.
1232      */
1233     PowerManagerInternal mLocalPowerManager;
1234
1235     /**
1236      * We want to hold a wake lock while running a voice interaction session, since
1237      * this may happen with the screen off and we need to keep the CPU running to
1238      * be able to continue to interact with the user.
1239      */
1240     PowerManager.WakeLock mVoiceWakeLock;
1241
1242     /**
1243      * State of external calls telling us if the device is awake or asleep.
1244      */
1245     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1246
1247     /**
1248      * A list of tokens that cause the top activity to be put to sleep.
1249      * They are used by components that may hide and block interaction with underlying
1250      * activities.
1251      */
1252     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253
1254     static final int LOCK_SCREEN_HIDDEN = 0;
1255     static final int LOCK_SCREEN_LEAVING = 1;
1256     static final int LOCK_SCREEN_SHOWN = 2;
1257     /**
1258      * State of external call telling us if the lock screen is shown.
1259      */
1260     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1261
1262     /**
1263      * Set if we are shutting down the system, similar to sleeping.
1264      */
1265     boolean mShuttingDown = false;
1266
1267     /**
1268      * Current sequence id for oom_adj computation traversal.
1269      */
1270     int mAdjSeq = 0;
1271
1272     /**
1273      * Current sequence id for process LRU updating.
1274      */
1275     int mLruSeq = 0;
1276
1277     /**
1278      * Keep track of the non-cached/empty process we last found, to help
1279      * determine how to distribute cached/empty processes next time.
1280      */
1281     int mNumNonCachedProcs = 0;
1282
1283     /**
1284      * Keep track of the number of cached hidden procs, to balance oom adj
1285      * distribution between those and empty procs.
1286      */
1287     int mNumCachedHiddenProcs = 0;
1288
1289     /**
1290      * Keep track of the number of service processes we last found, to
1291      * determine on the next iteration which should be B services.
1292      */
1293     int mNumServiceProcs = 0;
1294     int mNewNumAServiceProcs = 0;
1295     int mNewNumServiceProcs = 0;
1296
1297     /**
1298      * Allow the current computed overall memory level of the system to go down?
1299      * This is set to false when we are killing processes for reasons other than
1300      * memory management, so that the now smaller process list will not be taken as
1301      * an indication that memory is tighter.
1302      */
1303     boolean mAllowLowerMemLevel = false;
1304
1305     /**
1306      * The last computed memory level, for holding when we are in a state that
1307      * processes are going away for other reasons.
1308      */
1309     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1310
1311     /**
1312      * The last total number of process we have, to determine if changes actually look
1313      * like a shrinking number of process due to lower RAM.
1314      */
1315     int mLastNumProcesses;
1316
1317     /**
1318      * The uptime of the last time we performed idle maintenance.
1319      */
1320     long mLastIdleTime = SystemClock.uptimeMillis();
1321
1322     /**
1323      * Total time spent with RAM that has been added in the past since the last idle time.
1324      */
1325     long mLowRamTimeSinceLastIdle = 0;
1326
1327     /**
1328      * If RAM is currently low, when that horrible situation started.
1329      */
1330     long mLowRamStartTime = 0;
1331
1332     /**
1333      * For reporting to battery stats the current top application.
1334      */
1335     private String mCurResumedPackage = null;
1336     private int mCurResumedUid = -1;
1337
1338     /**
1339      * For reporting to battery stats the apps currently running foreground
1340      * service.  The ProcessMap is package/uid tuples; each of these contain
1341      * an array of the currently foreground processes.
1342      */
1343     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344             = new ProcessMap<ArrayList<ProcessRecord>>();
1345
1346     /**
1347      * This is set if we had to do a delayed dexopt of an app before launching
1348      * it, to increase the ANR timeouts in that case.
1349      */
1350     boolean mDidDexOpt;
1351
1352     /**
1353      * Set if the systemServer made a call to enterSafeMode.
1354      */
1355     boolean mSafeMode;
1356
1357     /**
1358      * If true, we are running under a test environment so will sample PSS from processes
1359      * much more rapidly to try to collect better data when the tests are rapidly
1360      * running through apps.
1361      */
1362     boolean mTestPssMode = false;
1363
1364     String mDebugApp = null;
1365     boolean mWaitForDebugger = false;
1366     boolean mDebugTransient = false;
1367     String mOrigDebugApp = null;
1368     boolean mOrigWaitForDebugger = false;
1369     boolean mAlwaysFinishActivities = false;
1370     boolean mLenientBackgroundCheck = false;
1371     boolean mForceResizableActivities;
1372     boolean mSupportsMultiWindow;
1373     boolean mSupportsFreeformWindowManagement;
1374     boolean mSupportsPictureInPicture;
1375     boolean mSupportsLeanbackOnly;
1376     Rect mDefaultPinnedStackBounds;
1377     IActivityController mController = null;
1378     boolean mControllerIsAMonkey = false;
1379     String mProfileApp = null;
1380     ProcessRecord mProfileProc = null;
1381     String mProfileFile;
1382     ParcelFileDescriptor mProfileFd;
1383     int mSamplingInterval = 0;
1384     boolean mAutoStopProfiler = false;
1385     int mProfileType = 0;
1386     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1387     String mMemWatchDumpProcName;
1388     String mMemWatchDumpFile;
1389     int mMemWatchDumpPid;
1390     int mMemWatchDumpUid;
1391     String mTrackAllocationApp = null;
1392     String mNativeDebuggingApp = null;
1393
1394     final long[] mTmpLong = new long[2];
1395
1396     static final class ProcessChangeItem {
1397         static final int CHANGE_ACTIVITIES = 1<<0;
1398         static final int CHANGE_PROCESS_STATE = 1<<1;
1399         int changes;
1400         int uid;
1401         int pid;
1402         int processState;
1403         boolean foregroundActivities;
1404     }
1405
1406     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1407     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1408
1409     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1410     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1411
1412     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1413     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1414
1415     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1416     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1417
1418     /**
1419      * Runtime CPU use collection thread.  This object's lock is used to
1420      * perform synchronization with the thread (notifying it to run).
1421      */
1422     final Thread mProcessCpuThread;
1423
1424     /**
1425      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1426      * Must acquire this object's lock when accessing it.
1427      * NOTE: this lock will be held while doing long operations (trawling
1428      * through all processes in /proc), so it should never be acquired by
1429      * any critical paths such as when holding the main activity manager lock.
1430      */
1431     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1432             MONITOR_THREAD_CPU_USAGE);
1433     final AtomicLong mLastCpuTime = new AtomicLong(0);
1434     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1435
1436     long mLastWriteTime = 0;
1437
1438     /**
1439      * Used to retain an update lock when the foreground activity is in
1440      * immersive mode.
1441      */
1442     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1443
1444     /**
1445      * Set to true after the system has finished booting.
1446      */
1447     boolean mBooted = false;
1448
1449     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1450     int mProcessLimitOverride = -1;
1451
1452     WindowManagerService mWindowManager;
1453     final ActivityThread mSystemThread;
1454
1455     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1456         final ProcessRecord mApp;
1457         final int mPid;
1458         final IApplicationThread mAppThread;
1459
1460         AppDeathRecipient(ProcessRecord app, int pid,
1461                 IApplicationThread thread) {
1462             if (DEBUG_ALL) Slog.v(
1463                 TAG, "New death recipient " + this
1464                 + " for thread " + thread.asBinder());
1465             mApp = app;
1466             mPid = pid;
1467             mAppThread = thread;
1468         }
1469
1470         @Override
1471         public void binderDied() {
1472             if (DEBUG_ALL) Slog.v(
1473                 TAG, "Death received in " + this
1474                 + " for thread " + mAppThread.asBinder());
1475             synchronized(ActivityManagerService.this) {
1476                 appDiedLocked(mApp, mPid, mAppThread, true);
1477             }
1478         }
1479     }
1480
1481     static final int SHOW_ERROR_UI_MSG = 1;
1482     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1483     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1484     static final int UPDATE_CONFIGURATION_MSG = 4;
1485     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1486     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1487     static final int SERVICE_TIMEOUT_MSG = 12;
1488     static final int UPDATE_TIME_ZONE = 13;
1489     static final int SHOW_UID_ERROR_UI_MSG = 14;
1490     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1491     static final int PROC_START_TIMEOUT_MSG = 20;
1492     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1493     static final int KILL_APPLICATION_MSG = 22;
1494     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1495     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1496     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1497     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1498     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1499     static final int CLEAR_DNS_CACHE_MSG = 28;
1500     static final int UPDATE_HTTP_PROXY_MSG = 29;
1501     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1502     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1503     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1504     static final int REPORT_MEM_USAGE_MSG = 33;
1505     static final int REPORT_USER_SWITCH_MSG = 34;
1506     static final int CONTINUE_USER_SWITCH_MSG = 35;
1507     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1508     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1509     static final int PERSIST_URI_GRANTS_MSG = 38;
1510     static final int REQUEST_ALL_PSS_MSG = 39;
1511     static final int START_PROFILES_MSG = 40;
1512     static final int UPDATE_TIME = 41;
1513     static final int SYSTEM_USER_START_MSG = 42;
1514     static final int SYSTEM_USER_CURRENT_MSG = 43;
1515     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1516     static final int FINISH_BOOTING_MSG = 45;
1517     static final int START_USER_SWITCH_UI_MSG = 46;
1518     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1519     static final int DISMISS_DIALOG_UI_MSG = 48;
1520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1521     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1522     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1523     static final int DELETE_DUMPHEAP_MSG = 52;
1524     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1525     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1526     static final int REPORT_TIME_TRACKER_MSG = 55;
1527     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1528     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1529     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1530     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1531     static final int IDLE_UIDS_MSG = 60;
1532     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1533     static final int LOG_STACK_STATE = 62;
1534     static final int VR_MODE_CHANGE_MSG = 63;
1535     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1536     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1537     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1538     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1539     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1540     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1541     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1542
1543     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1544     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1545     static final int FIRST_COMPAT_MODE_MSG = 300;
1546     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1547
1548     static ServiceThread sKillThread = null;
1549     static KillHandler sKillHandler = null;
1550
1551     CompatModeDialog mCompatModeDialog;
1552     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1553     long mLastMemUsageReportTime = 0;
1554
1555     /**
1556      * Flag whether the current user is a "monkey", i.e. whether
1557      * the UI is driven by a UI automation tool.
1558      */
1559     private boolean mUserIsMonkey;
1560
1561     /** Flag whether the device has a Recents UI */
1562     boolean mHasRecents;
1563
1564     /** The dimensions of the thumbnails in the Recents UI. */
1565     int mThumbnailWidth;
1566     int mThumbnailHeight;
1567     float mFullscreenThumbnailScale;
1568
1569     final ServiceThread mHandlerThread;
1570     final MainHandler mHandler;
1571     final UiHandler mUiHandler;
1572
1573     PackageManagerInternal mPackageManagerInt;
1574
1575     // VoiceInteraction session ID that changes for each new request except when
1576     // being called for multiwindow assist in a single session.
1577     private int mViSessionId = 1000;
1578
1579     final boolean mPermissionReviewRequired;
1580
1581     final class KillHandler extends Handler {
1582         static final int KILL_PROCESS_GROUP_MSG = 4000;
1583
1584         public KillHandler(Looper looper) {
1585             super(looper, null, true);
1586         }
1587
1588         @Override
1589         public void handleMessage(Message msg) {
1590             switch (msg.what) {
1591                 case KILL_PROCESS_GROUP_MSG:
1592                 {
1593                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1594                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1595                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1596                 }
1597                 break;
1598
1599                 default:
1600                     super.handleMessage(msg);
1601             }
1602         }
1603     }
1604
1605     final class UiHandler extends Handler {
1606         public UiHandler() {
1607             super(com.android.server.UiThread.get().getLooper(), null, true);
1608         }
1609
1610         @Override
1611         public void handleMessage(Message msg) {
1612             switch (msg.what) {
1613             case SHOW_ERROR_UI_MSG: {
1614                 mAppErrors.handleShowAppErrorUi(msg);
1615                 ensureBootCompleted();
1616             } break;
1617             case SHOW_NOT_RESPONDING_UI_MSG: {
1618                 mAppErrors.handleShowAnrUi(msg);
1619                 ensureBootCompleted();
1620             } break;
1621             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1622                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1623                 synchronized (ActivityManagerService.this) {
1624                     ProcessRecord proc = (ProcessRecord) data.get("app");
1625                     if (proc == null) {
1626                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1627                         break;
1628                     }
1629                     if (proc.crashDialog != null) {
1630                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1631                         return;
1632                     }
1633                     AppErrorResult res = (AppErrorResult) data.get("result");
1634                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1635                         Dialog d = new StrictModeViolationDialog(mContext,
1636                                 ActivityManagerService.this, res, proc);
1637                         d.show();
1638                         proc.crashDialog = d;
1639                     } else {
1640                         // The device is asleep, so just pretend that the user
1641                         // saw a crash dialog and hit "force quit".
1642                         res.set(0);
1643                     }
1644                 }
1645                 ensureBootCompleted();
1646             } break;
1647             case SHOW_FACTORY_ERROR_UI_MSG: {
1648                 Dialog d = new FactoryErrorDialog(
1649                     mContext, msg.getData().getCharSequence("msg"));
1650                 d.show();
1651                 ensureBootCompleted();
1652             } break;
1653             case WAIT_FOR_DEBUGGER_UI_MSG: {
1654                 synchronized (ActivityManagerService.this) {
1655                     ProcessRecord app = (ProcessRecord)msg.obj;
1656                     if (msg.arg1 != 0) {
1657                         if (!app.waitedForDebugger) {
1658                             Dialog d = new AppWaitingForDebuggerDialog(
1659                                     ActivityManagerService.this,
1660                                     mContext, app);
1661                             app.waitDialog = d;
1662                             app.waitedForDebugger = true;
1663                             d.show();
1664                         }
1665                     } else {
1666                         if (app.waitDialog != null) {
1667                             app.waitDialog.dismiss();
1668                             app.waitDialog = null;
1669                         }
1670                     }
1671                 }
1672             } break;
1673             case SHOW_UID_ERROR_UI_MSG: {
1674                 if (mShowDialogs) {
1675                     AlertDialog d = new BaseErrorDialog(mContext);
1676                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1677                     d.setCancelable(false);
1678                     d.setTitle(mContext.getText(R.string.android_system_label));
1679                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1680                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1681                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1682                     d.show();
1683                 }
1684             } break;
1685             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1686                 if (mShowDialogs) {
1687                     AlertDialog d = new BaseErrorDialog(mContext);
1688                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1689                     d.setCancelable(false);
1690                     d.setTitle(mContext.getText(R.string.android_system_label));
1691                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1692                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1693                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694                     d.show();
1695                 }
1696             } break;
1697             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1698                 synchronized (ActivityManagerService.this) {
1699                     ActivityRecord ar = (ActivityRecord) msg.obj;
1700                     if (mCompatModeDialog != null) {
1701                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1702                                 ar.info.applicationInfo.packageName)) {
1703                             return;
1704                         }
1705                         mCompatModeDialog.dismiss();
1706                         mCompatModeDialog = null;
1707                     }
1708                     if (ar != null && false) {
1709                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1710                                 ar.packageName)) {
1711                             int mode = mCompatModePackages.computeCompatModeLocked(
1712                                     ar.info.applicationInfo);
1713                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1714                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1715                                 mCompatModeDialog = new CompatModeDialog(
1716                                         ActivityManagerService.this, mContext,
1717                                         ar.info.applicationInfo);
1718                                 mCompatModeDialog.show();
1719                             }
1720                         }
1721                     }
1722                 }
1723                 break;
1724             }
1725             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1726                 synchronized (ActivityManagerService.this) {
1727                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1728                     if (mUnsupportedDisplaySizeDialog != null) {
1729                         mUnsupportedDisplaySizeDialog.dismiss();
1730                         mUnsupportedDisplaySizeDialog = null;
1731                     }
1732                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1733                             ar.packageName)) {
1734                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736                         mUnsupportedDisplaySizeDialog.show();
1737                     }
1738                 }
1739                 break;
1740             }
1741             case START_USER_SWITCH_UI_MSG: {
1742                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1743                 break;
1744             }
1745             case DISMISS_DIALOG_UI_MSG: {
1746                 final Dialog d = (Dialog) msg.obj;
1747                 d.dismiss();
1748                 break;
1749             }
1750             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751                 dispatchProcessesChanged();
1752                 break;
1753             }
1754             case DISPATCH_PROCESS_DIED_UI_MSG: {
1755                 final int pid = msg.arg1;
1756                 final int uid = msg.arg2;
1757                 dispatchProcessDied(pid, uid);
1758                 break;
1759             }
1760             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761                 dispatchUidsChanged();
1762             } break;
1763             }
1764         }
1765     }
1766
1767     final class MainHandler extends Handler {
1768         public MainHandler(Looper looper) {
1769             super(looper, null, true);
1770         }
1771
1772         @Override
1773         public void handleMessage(Message msg) {
1774             switch (msg.what) {
1775             case UPDATE_CONFIGURATION_MSG: {
1776                 final ContentResolver resolver = mContext.getContentResolver();
1777                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1778                         msg.arg1);
1779             } break;
1780             case GC_BACKGROUND_PROCESSES_MSG: {
1781                 synchronized (ActivityManagerService.this) {
1782                     performAppGcsIfAppropriateLocked();
1783                 }
1784             } break;
1785             case SERVICE_TIMEOUT_MSG: {
1786                 if (mDidDexOpt) {
1787                     mDidDexOpt = false;
1788                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1789                     nmsg.obj = msg.obj;
1790                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1791                     return;
1792                 }
1793                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1794             } break;
1795             case UPDATE_TIME_ZONE: {
1796                 synchronized (ActivityManagerService.this) {
1797                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798                         ProcessRecord r = mLruProcesses.get(i);
1799                         if (r.thread != null) {
1800                             try {
1801                                 r.thread.updateTimeZone();
1802                             } catch (RemoteException ex) {
1803                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1804                             }
1805                         }
1806                     }
1807                 }
1808             } break;
1809             case CLEAR_DNS_CACHE_MSG: {
1810                 synchronized (ActivityManagerService.this) {
1811                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812                         ProcessRecord r = mLruProcesses.get(i);
1813                         if (r.thread != null) {
1814                             try {
1815                                 r.thread.clearDnsCache();
1816                             } catch (RemoteException ex) {
1817                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1818                             }
1819                         }
1820                     }
1821                 }
1822             } break;
1823             case UPDATE_HTTP_PROXY_MSG: {
1824                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1825                 String host = "";
1826                 String port = "";
1827                 String exclList = "";
1828                 Uri pacFileUrl = Uri.EMPTY;
1829                 if (proxy != null) {
1830                     host = proxy.getHost();
1831                     port = Integer.toString(proxy.getPort());
1832                     exclList = proxy.getExclusionListAsString();
1833                     pacFileUrl = proxy.getPacFileUrl();
1834                 }
1835                 synchronized (ActivityManagerService.this) {
1836                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837                         ProcessRecord r = mLruProcesses.get(i);
1838                         if (r.thread != null) {
1839                             try {
1840                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841                             } catch (RemoteException ex) {
1842                                 Slog.w(TAG, "Failed to update http proxy for: " +
1843                                         r.info.processName);
1844                             }
1845                         }
1846                     }
1847                 }
1848             } break;
1849             case PROC_START_TIMEOUT_MSG: {
1850                 if (mDidDexOpt) {
1851                     mDidDexOpt = false;
1852                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1853                     nmsg.obj = msg.obj;
1854                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1855                     return;
1856                 }
1857                 ProcessRecord app = (ProcessRecord)msg.obj;
1858                 synchronized (ActivityManagerService.this) {
1859                     processStartTimedOutLocked(app);
1860                 }
1861             } break;
1862             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863                 ProcessRecord app = (ProcessRecord)msg.obj;
1864                 synchronized (ActivityManagerService.this) {
1865                     processContentProviderPublishTimedOutLocked(app);
1866                 }
1867             } break;
1868             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869                 synchronized (ActivityManagerService.this) {
1870                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1871                 }
1872             } break;
1873             case KILL_APPLICATION_MSG: {
1874                 synchronized (ActivityManagerService.this) {
1875                     final int appId = msg.arg1;
1876                     final int userId = msg.arg2;
1877                     Bundle bundle = (Bundle)msg.obj;
1878                     String pkg = bundle.getString("pkg");
1879                     String reason = bundle.getString("reason");
1880                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1881                             false, userId, reason);
1882                 }
1883             } break;
1884             case FINALIZE_PENDING_INTENT_MSG: {
1885                 ((PendingIntentRecord)msg.obj).completeFinalize();
1886             } break;
1887             case POST_HEAVY_NOTIFICATION_MSG: {
1888                 INotificationManager inm = NotificationManager.getService();
1889                 if (inm == null) {
1890                     return;
1891                 }
1892
1893                 ActivityRecord root = (ActivityRecord)msg.obj;
1894                 ProcessRecord process = root.app;
1895                 if (process == null) {
1896                     return;
1897                 }
1898
1899                 try {
1900                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1901                     String text = mContext.getString(R.string.heavy_weight_notification,
1902                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903                     Notification notification = new Notification.Builder(context)
1904                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1905                             .setWhen(0)
1906                             .setOngoing(true)
1907                             .setTicker(text)
1908                             .setColor(mContext.getColor(
1909                                     com.android.internal.R.color.system_notification_accent_color))
1910                             .setContentTitle(text)
1911                             .setContentText(
1912                                     mContext.getText(R.string.heavy_weight_notification_detail))
1913                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915                                     new UserHandle(root.userId)))
1916                             .build();
1917                     try {
1918                         int[] outId = new int[1];
1919                         inm.enqueueNotificationWithTag("android", "android", null,
1920                                 R.string.heavy_weight_notification,
1921                                 notification, outId, root.userId);
1922                     } catch (RuntimeException e) {
1923                         Slog.w(ActivityManagerService.TAG,
1924                                 "Error showing notification for heavy-weight app", e);
1925                     } catch (RemoteException e) {
1926                     }
1927                 } catch (NameNotFoundException e) {
1928                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1929                 }
1930             } break;
1931             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932                 INotificationManager inm = NotificationManager.getService();
1933                 if (inm == null) {
1934                     return;
1935                 }
1936                 try {
1937                     inm.cancelNotificationWithTag("android", null,
1938                             R.string.heavy_weight_notification,  msg.arg1);
1939                 } catch (RuntimeException e) {
1940                     Slog.w(ActivityManagerService.TAG,
1941                             "Error canceling notification for service", e);
1942                 } catch (RemoteException e) {
1943                 }
1944             } break;
1945             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946                 synchronized (ActivityManagerService.this) {
1947                     checkExcessivePowerUsageLocked(true);
1948                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1951                 }
1952             } break;
1953             case REPORT_MEM_USAGE_MSG: {
1954                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955                 Thread thread = new Thread() {
1956                     @Override public void run() {
1957                         reportMemUsage(memInfos);
1958                     }
1959                 };
1960                 thread.start();
1961                 break;
1962             }
1963             case REPORT_USER_SWITCH_MSG: {
1964                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1965                 break;
1966             }
1967             case CONTINUE_USER_SWITCH_MSG: {
1968                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1969                 break;
1970             }
1971             case USER_SWITCH_TIMEOUT_MSG: {
1972                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1973                 break;
1974             }
1975             case IMMERSIVE_MODE_LOCK_MSG: {
1976                 final boolean nextState = (msg.arg1 != 0);
1977                 if (mUpdateLock.isHeld() != nextState) {
1978                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1979                             "Applying new update lock state '" + nextState
1980                             + "' for " + (ActivityRecord)msg.obj);
1981                     if (nextState) {
1982                         mUpdateLock.acquire();
1983                     } else {
1984                         mUpdateLock.release();
1985                     }
1986                 }
1987                 break;
1988             }
1989             case PERSIST_URI_GRANTS_MSG: {
1990                 writeGrantedUriPermissions();
1991                 break;
1992             }
1993             case REQUEST_ALL_PSS_MSG: {
1994                 synchronized (ActivityManagerService.this) {
1995                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1996                 }
1997                 break;
1998             }
1999             case START_PROFILES_MSG: {
2000                 synchronized (ActivityManagerService.this) {
2001                     mUserController.startProfilesLocked();
2002                 }
2003                 break;
2004             }
2005             case UPDATE_TIME: {
2006                 synchronized (ActivityManagerService.this) {
2007                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008                         ProcessRecord r = mLruProcesses.get(i);
2009                         if (r.thread != null) {
2010                             try {
2011                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2012                             } catch (RemoteException ex) {
2013                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2014                             }
2015                         }
2016                     }
2017                 }
2018                 break;
2019             }
2020             case SYSTEM_USER_START_MSG: {
2021                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2022                         Integer.toString(msg.arg1), msg.arg1);
2023                 mSystemServiceManager.startUser(msg.arg1);
2024                 break;
2025             }
2026             case SYSTEM_USER_UNLOCK_MSG: {
2027                 final int userId = msg.arg1;
2028                 mSystemServiceManager.unlockUser(userId);
2029                 synchronized (ActivityManagerService.this) {
2030                     mRecentTasks.loadUserRecentsLocked(userId);
2031                 }
2032                 if (userId == UserHandle.USER_SYSTEM) {
2033                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2034                 }
2035                 installEncryptionUnawareProviders(userId);
2036                 mUserController.finishUserUnlocked((UserState) msg.obj);
2037                 break;
2038             }
2039             case SYSTEM_USER_CURRENT_MSG: {
2040                 mBatteryStatsService.noteEvent(
2041                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2042                         Integer.toString(msg.arg2), msg.arg2);
2043                 mBatteryStatsService.noteEvent(
2044                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2045                         Integer.toString(msg.arg1), msg.arg1);
2046                 mSystemServiceManager.switchUser(msg.arg1);
2047                 break;
2048             }
2049             case ENTER_ANIMATION_COMPLETE_MSG: {
2050                 synchronized (ActivityManagerService.this) {
2051                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2052                     if (r != null && r.app != null && r.app.thread != null) {
2053                         try {
2054                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2055                         } catch (RemoteException e) {
2056                         }
2057                     }
2058                 }
2059                 break;
2060             }
2061             case FINISH_BOOTING_MSG: {
2062                 if (msg.arg1 != 0) {
2063                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2064                     finishBooting();
2065                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2066                 }
2067                 if (msg.arg2 != 0) {
2068                     enableScreenAfterBoot();
2069                 }
2070                 break;
2071             }
2072             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2073                 try {
2074                     Locale l = (Locale) msg.obj;
2075                     IBinder service = ServiceManager.getService("mount");
2076                     IMountService mountService = IMountService.Stub.asInterface(service);
2077                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2078                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2079                 } catch (RemoteException e) {
2080                     Log.e(TAG, "Error storing locale for decryption UI", e);
2081                 }
2082                 break;
2083             }
2084             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2085                 synchronized (ActivityManagerService.this) {
2086                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2087                         try {
2088                             // Make a one-way callback to the listener
2089                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2090                         } catch (RemoteException e){
2091                             // Handled by the RemoteCallbackList
2092                         }
2093                     }
2094                     mTaskStackListeners.finishBroadcast();
2095                 }
2096                 break;
2097             }
2098             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2099                 synchronized (ActivityManagerService.this) {
2100                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2101                         try {
2102                             // Make a one-way callback to the listener
2103                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2104                         } catch (RemoteException e){
2105                             // Handled by the RemoteCallbackList
2106                         }
2107                     }
2108                     mTaskStackListeners.finishBroadcast();
2109                 }
2110                 break;
2111             }
2112             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2113                 synchronized (ActivityManagerService.this) {
2114                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2115                         try {
2116                             // Make a one-way callback to the listener
2117                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2118                         } catch (RemoteException e){
2119                             // Handled by the RemoteCallbackList
2120                         }
2121                     }
2122                     mTaskStackListeners.finishBroadcast();
2123                 }
2124                 break;
2125             }
2126             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2127                 synchronized (ActivityManagerService.this) {
2128                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2129                         try {
2130                             // Make a one-way callback to the listener
2131                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2132                         } catch (RemoteException e){
2133                             // Handled by the RemoteCallbackList
2134                         }
2135                     }
2136                     mTaskStackListeners.finishBroadcast();
2137                 }
2138                 break;
2139             }
2140             case NOTIFY_FORCED_RESIZABLE_MSG: {
2141                 synchronized (ActivityManagerService.this) {
2142                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2143                         try {
2144                             // Make a one-way callback to the listener
2145                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2146                                     (String) msg.obj, msg.arg1);
2147                         } catch (RemoteException e){
2148                             // Handled by the RemoteCallbackList
2149                         }
2150                     }
2151                     mTaskStackListeners.finishBroadcast();
2152                 }
2153                 break;
2154             }
2155                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2156                     synchronized (ActivityManagerService.this) {
2157                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2158                             try {
2159                                 // Make a one-way callback to the listener
2160                                 mTaskStackListeners.getBroadcastItem(i)
2161                                         .onActivityDismissingDockedStack();
2162                             } catch (RemoteException e){
2163                                 // Handled by the RemoteCallbackList
2164                             }
2165                         }
2166                         mTaskStackListeners.finishBroadcast();
2167                     }
2168                     break;
2169                 }
2170             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2171                 final int uid = msg.arg1;
2172                 final byte[] firstPacket = (byte[]) msg.obj;
2173
2174                 synchronized (mPidsSelfLocked) {
2175                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2176                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2177                         if (p.uid == uid) {
2178                             try {
2179                                 p.thread.notifyCleartextNetwork(firstPacket);
2180                             } catch (RemoteException ignored) {
2181                             }
2182                         }
2183                     }
2184                 }
2185                 break;
2186             }
2187             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2188                 final String procName;
2189                 final int uid;
2190                 final long memLimit;
2191                 final String reportPackage;
2192                 synchronized (ActivityManagerService.this) {
2193                     procName = mMemWatchDumpProcName;
2194                     uid = mMemWatchDumpUid;
2195                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2196                     if (val == null) {
2197                         val = mMemWatchProcesses.get(procName, 0);
2198                     }
2199                     if (val != null) {
2200                         memLimit = val.first;
2201                         reportPackage = val.second;
2202                     } else {
2203                         memLimit = 0;
2204                         reportPackage = null;
2205                     }
2206                 }
2207                 if (procName == null) {
2208                     return;
2209                 }
2210
2211                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2212                         "Showing dump heap notification from " + procName + "/" + uid);
2213
2214                 INotificationManager inm = NotificationManager.getService();
2215                 if (inm == null) {
2216                     return;
2217                 }
2218
2219                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2220
2221
2222                 Intent deleteIntent = new Intent();
2223                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2224                 Intent intent = new Intent();
2225                 intent.setClassName("android", DumpHeapActivity.class.getName());
2226                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2227                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2228                 if (reportPackage != null) {
2229                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2230                 }
2231                 int userId = UserHandle.getUserId(uid);
2232                 Notification notification = new Notification.Builder(mContext)
2233                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2234                         .setWhen(0)
2235                         .setOngoing(true)
2236                         .setAutoCancel(true)
2237                         .setTicker(text)
2238                         .setColor(mContext.getColor(
2239                                 com.android.internal.R.color.system_notification_accent_color))
2240                         .setContentTitle(text)
2241                         .setContentText(
2242                                 mContext.getText(R.string.dump_heap_notification_detail))
2243                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2244                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2245                                 new UserHandle(userId)))
2246                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2247                                 deleteIntent, 0, UserHandle.SYSTEM))
2248                         .build();
2249
2250                 try {
2251                     int[] outId = new int[1];
2252                     inm.enqueueNotificationWithTag("android", "android", null,
2253                             R.string.dump_heap_notification,
2254                             notification, outId, userId);
2255                 } catch (RuntimeException e) {
2256                     Slog.w(ActivityManagerService.TAG,
2257                             "Error showing notification for dump heap", e);
2258                 } catch (RemoteException e) {
2259                 }
2260             } break;
2261             case DELETE_DUMPHEAP_MSG: {
2262                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2263                         DumpHeapActivity.JAVA_URI,
2264                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2265                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2266                         UserHandle.myUserId());
2267                 synchronized (ActivityManagerService.this) {
2268                     mMemWatchDumpFile = null;
2269                     mMemWatchDumpProcName = null;
2270                     mMemWatchDumpPid = -1;
2271                     mMemWatchDumpUid = -1;
2272                 }
2273             } break;
2274             case FOREGROUND_PROFILE_CHANGED_MSG: {
2275                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2276             } break;
2277             case REPORT_TIME_TRACKER_MSG: {
2278                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2279                 tracker.deliverResult(mContext);
2280             } break;
2281             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2282                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2283             } break;
2284             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2285                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2286                 try {
2287                     connection.shutdown();
2288                 } catch (RemoteException e) {
2289                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2290                 }
2291                 // Only a UiAutomation can set this flag and now that
2292                 // it is finished we make sure it is reset to its default.
2293                 mUserIsMonkey = false;
2294             } break;
2295             case APP_BOOST_DEACTIVATE_MSG: {
2296                 synchronized(ActivityManagerService.this) {
2297                     if (mIsBoosted) {
2298                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2299                             nativeMigrateFromBoost();
2300                             mIsBoosted = false;
2301                             mBoostStartTime = 0;
2302                         } else {
2303                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2304                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2305                         }
2306                     }
2307                 }
2308             } break;
2309             case IDLE_UIDS_MSG: {
2310                 idleUids();
2311             } break;
2312             case LOG_STACK_STATE: {
2313                 synchronized (ActivityManagerService.this) {
2314                     mStackSupervisor.logStackState();
2315                 }
2316             } break;
2317             case VR_MODE_CHANGE_MSG: {
2318                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319                 if (vrService == null) {
2320                     break;
2321                 }
2322                 final ActivityRecord r = (ActivityRecord) msg.obj;
2323                 boolean vrMode;
2324                 ComponentName requestedPackage;
2325                 ComponentName callingPackage;
2326                 int userId;
2327                 synchronized (ActivityManagerService.this) {
2328                     vrMode = r.requestedVrComponent != null;
2329                     requestedPackage = r.requestedVrComponent;
2330                     userId = r.userId;
2331                     callingPackage = r.info.getComponentName();
2332                     if (mInVrMode != vrMode) {
2333                         mInVrMode = vrMode;
2334                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2335                         if (r.app != null) {
2336                             ProcessRecord proc = r.app;
2337                             if (proc.vrThreadTid > 0) {
2338                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2339                                     try {
2340                                         if (mInVrMode == true) {
2341                                             Process.setThreadScheduler(proc.vrThreadTid,
2342                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2343                                         } else {
2344                                             Process.setThreadScheduler(proc.vrThreadTid,
2345                                                 Process.SCHED_OTHER, 0);
2346                                         }
2347                                     } catch (IllegalArgumentException e) {
2348                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349                                                 + " not exist:\n" + e);
2350                                     }
2351                                 }
2352                             }
2353                         }
2354                     }
2355                 }
2356                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2357             } break;
2358             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359                 final ActivityRecord r = (ActivityRecord) msg.obj;
2360                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2361                 if (needsVrMode) {
2362                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363                             r.info.getComponentName(), false);
2364                 }
2365             } break;
2366             }
2367         }
2368     };
2369
2370     static final int COLLECT_PSS_BG_MSG = 1;
2371
2372     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2373         @Override
2374         public void handleMessage(Message msg) {
2375             switch (msg.what) {
2376             case COLLECT_PSS_BG_MSG: {
2377                 long start = SystemClock.uptimeMillis();
2378                 MemInfoReader memInfo = null;
2379                 synchronized (ActivityManagerService.this) {
2380                     if (mFullPssPending) {
2381                         mFullPssPending = false;
2382                         memInfo = new MemInfoReader();
2383                     }
2384                 }
2385                 if (memInfo != null) {
2386                     updateCpuStatsNow();
2387                     long nativeTotalPss = 0;
2388                     final List<ProcessCpuTracker.Stats> stats;
2389                     synchronized (mProcessCpuTracker) {
2390                         stats = mProcessCpuTracker.getStats( (st)-> {
2391                             return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2392                         });
2393                     }
2394                     final int N = stats.size();
2395                     for (int j = 0; j < N; j++) {
2396                         synchronized (mPidsSelfLocked) {
2397                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2398                                 // This is one of our own processes; skip it.
2399                                 continue;
2400                             }
2401                         }
2402                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2403                     }
2404                     memInfo.readMemInfo();
2405                     synchronized (ActivityManagerService.this) {
2406                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2407                                 + (SystemClock.uptimeMillis()-start) + "ms");
2408                         final long cachedKb = memInfo.getCachedSizeKb();
2409                         final long freeKb = memInfo.getFreeSizeKb();
2410                         final long zramKb = memInfo.getZramTotalSizeKb();
2411                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2412                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2413                                 kernelKb*1024, nativeTotalPss*1024);
2414                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2415                                 nativeTotalPss);
2416                     }
2417                 }
2418
2419                 int num = 0;
2420                 long[] tmp = new long[2];
2421                 do {
2422                     ProcessRecord proc;
2423                     int procState;
2424                     int pid;
2425                     long lastPssTime;
2426                     synchronized (ActivityManagerService.this) {
2427                         if (mPendingPssProcesses.size() <= 0) {
2428                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2429                                     "Collected PSS of " + num + " processes in "
2430                                     + (SystemClock.uptimeMillis() - start) + "ms");
2431                             mPendingPssProcesses.clear();
2432                             return;
2433                         }
2434                         proc = mPendingPssProcesses.remove(0);
2435                         procState = proc.pssProcState;
2436                         lastPssTime = proc.lastPssTime;
2437                         if (proc.thread != null && procState == proc.setProcState
2438                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2439                                         < SystemClock.uptimeMillis()) {
2440                             pid = proc.pid;
2441                         } else {
2442                             proc = null;
2443                             pid = 0;
2444                         }
2445                     }
2446                     if (proc != null) {
2447                         long pss = Debug.getPss(pid, tmp, null);
2448                         synchronized (ActivityManagerService.this) {
2449                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2450                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2451                                 num++;
2452                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2453                                         SystemClock.uptimeMillis());
2454                             }
2455                         }
2456                     }
2457                 } while (true);
2458             }
2459             }
2460         }
2461     };
2462
2463     public void setSystemProcess() {
2464         try {
2465             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2466             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2467             ServiceManager.addService("meminfo", new MemBinder(this));
2468             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2469             ServiceManager.addService("dbinfo", new DbBinder(this));
2470             if (MONITOR_CPU_USAGE) {
2471                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2472             }
2473             ServiceManager.addService("permission", new PermissionController(this));
2474             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2475
2476             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2477                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2478             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2479
2480             synchronized (this) {
2481                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2482                 app.persistent = true;
2483                 app.pid = MY_PID;
2484                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2485                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2486                 synchronized (mPidsSelfLocked) {
2487                     mPidsSelfLocked.put(app.pid, app);
2488                 }
2489                 updateLruProcessLocked(app, false, null);
2490                 updateOomAdjLocked();
2491             }
2492         } catch (PackageManager.NameNotFoundException e) {
2493             throw new RuntimeException(
2494                     "Unable to find android system package", e);
2495         }
2496     }
2497
2498     public void setWindowManager(WindowManagerService wm) {
2499         mWindowManager = wm;
2500         mStackSupervisor.setWindowManager(wm);
2501         mActivityStarter.setWindowManager(wm);
2502     }
2503
2504     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2505         mUsageStatsService = usageStatsManager;
2506     }
2507
2508     public void startObservingNativeCrashes() {
2509         final NativeCrashListener ncl = new NativeCrashListener(this);
2510         ncl.start();
2511     }
2512
2513     public IAppOpsService getAppOpsService() {
2514         return mAppOpsService;
2515     }
2516
2517     static class MemBinder extends Binder {
2518         ActivityManagerService mActivityManagerService;
2519         MemBinder(ActivityManagerService activityManagerService) {
2520             mActivityManagerService = activityManagerService;
2521         }
2522
2523         @Override
2524         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526                     != PackageManager.PERMISSION_GRANTED) {
2527                 pw.println("Permission Denial: can't dump meminfo from from pid="
2528                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529                         + " without permission " + android.Manifest.permission.DUMP);
2530                 return;
2531             }
2532
2533             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2534         }
2535     }
2536
2537     static class GraphicsBinder extends Binder {
2538         ActivityManagerService mActivityManagerService;
2539         GraphicsBinder(ActivityManagerService activityManagerService) {
2540             mActivityManagerService = activityManagerService;
2541         }
2542
2543         @Override
2544         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546                     != PackageManager.PERMISSION_GRANTED) {
2547                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2548                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549                         + " without permission " + android.Manifest.permission.DUMP);
2550                 return;
2551             }
2552
2553             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2554         }
2555     }
2556
2557     static class DbBinder extends Binder {
2558         ActivityManagerService mActivityManagerService;
2559         DbBinder(ActivityManagerService activityManagerService) {
2560             mActivityManagerService = activityManagerService;
2561         }
2562
2563         @Override
2564         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2565             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2566                     != PackageManager.PERMISSION_GRANTED) {
2567                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2568                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2569                         + " without permission " + android.Manifest.permission.DUMP);
2570                 return;
2571             }
2572
2573             mActivityManagerService.dumpDbInfo(fd, pw, args);
2574         }
2575     }
2576
2577     static class CpuBinder extends Binder {
2578         ActivityManagerService mActivityManagerService;
2579         CpuBinder(ActivityManagerService activityManagerService) {
2580             mActivityManagerService = activityManagerService;
2581         }
2582
2583         @Override
2584         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2585             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2586                     != PackageManager.PERMISSION_GRANTED) {
2587                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2588                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2589                         + " without permission " + android.Manifest.permission.DUMP);
2590                 return;
2591             }
2592
2593             synchronized (mActivityManagerService.mProcessCpuTracker) {
2594                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2595                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2596                         SystemClock.uptimeMillis()));
2597             }
2598         }
2599     }
2600
2601     public static final class Lifecycle extends SystemService {
2602         private final ActivityManagerService mService;
2603
2604         public Lifecycle(Context context) {
2605             super(context);
2606             mService = new ActivityManagerService(context);
2607         }
2608
2609         @Override
2610         public void onStart() {
2611             mService.start();
2612         }
2613
2614         public ActivityManagerService getService() {
2615             return mService;
2616         }
2617     }
2618
2619     // Note: This method is invoked on the main thread but may need to attach various
2620     // handlers to other threads.  So take care to be explicit about the looper.
2621     public ActivityManagerService(Context systemContext) {
2622         mContext = systemContext;
2623         mFactoryTest = FactoryTest.getMode();
2624         mSystemThread = ActivityThread.currentActivityThread();
2625
2626         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2627
2628         mPermissionReviewRequired = mContext.getResources().getBoolean(
2629                 com.android.internal.R.bool.config_permissionReviewRequired);
2630
2631         mHandlerThread = new ServiceThread(TAG,
2632                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2633         mHandlerThread.start();
2634         mHandler = new MainHandler(mHandlerThread.getLooper());
2635         mUiHandler = new UiHandler();
2636
2637         /* static; one-time init here */
2638         if (sKillHandler == null) {
2639             sKillThread = new ServiceThread(TAG + ":kill",
2640                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641             sKillThread.start();
2642             sKillHandler = new KillHandler(sKillThread.getLooper());
2643         }
2644
2645         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646                 "foreground", BROADCAST_FG_TIMEOUT, false);
2647         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648                 "background", BROADCAST_BG_TIMEOUT, true);
2649         mBroadcastQueues[0] = mFgBroadcastQueue;
2650         mBroadcastQueues[1] = mBgBroadcastQueue;
2651
2652         mServices = new ActiveServices(this);
2653         mProviderMap = new ProviderMap(this);
2654         mAppErrors = new AppErrors(mContext, this);
2655
2656         // TODO: Move creation of battery stats service outside of activity manager service.
2657         File dataDir = Environment.getDataDirectory();
2658         File systemDir = new File(dataDir, "system");
2659         systemDir.mkdirs();
2660         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661         mBatteryStatsService.getActiveStatistics().readLocked();
2662         mBatteryStatsService.scheduleWriteToDisk();
2663         mOnBattery = DEBUG_POWER ? true
2664                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665         mBatteryStatsService.getActiveStatistics().setCallback(this);
2666
2667         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2668
2669         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671                 new IAppOpsCallback.Stub() {
2672                     @Override public void opChanged(int op, int uid, String packageName) {
2673                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674                             if (mAppOpsService.checkOperation(op, uid, packageName)
2675                                     != AppOpsManager.MODE_ALLOWED) {
2676                                 runInBackgroundDisabled(uid);
2677                             }
2678                         }
2679                     }
2680                 });
2681
2682         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2683
2684         mUserController = new UserController(this);
2685
2686         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2688
2689         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690             mUseFifoUiScheduling = true;
2691         }
2692
2693         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2694
2695         mConfiguration.setToDefaults();
2696         mConfiguration.setLocales(LocaleList.getDefault());
2697
2698         mConfigurationSeq = mConfiguration.seq = 1;
2699         mProcessCpuTracker.init();
2700
2701         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2702         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2703         mStackSupervisor = new ActivityStackSupervisor(this);
2704         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2706
2707         mProcessCpuThread = new Thread("CpuTracker") {
2708             @Override
2709             public void run() {
2710                 while (true) {
2711                     try {
2712                         try {
2713                             synchronized(this) {
2714                                 final long now = SystemClock.uptimeMillis();
2715                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2716                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2717                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2718                                 //        + ", write delay=" + nextWriteDelay);
2719                                 if (nextWriteDelay < nextCpuDelay) {
2720                                     nextCpuDelay = nextWriteDelay;
2721                                 }
2722                                 if (nextCpuDelay > 0) {
2723                                     mProcessCpuMutexFree.set(true);
2724                                     this.wait(nextCpuDelay);
2725                                 }
2726                             }
2727                         } catch (InterruptedException e) {
2728                         }
2729                         updateCpuStatsNow();
2730                     } catch (Exception e) {
2731                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2732                     }
2733                 }
2734             }
2735         };
2736
2737         Watchdog.getInstance().addMonitor(this);
2738         Watchdog.getInstance().addThread(mHandler);
2739     }
2740
2741     public void setSystemServiceManager(SystemServiceManager mgr) {
2742         mSystemServiceManager = mgr;
2743     }
2744
2745     public void setInstaller(Installer installer) {
2746         mInstaller = installer;
2747     }
2748
2749     private void start() {
2750         Process.removeAllProcessGroups();
2751         mProcessCpuThread.start();
2752
2753         mBatteryStatsService.publish(mContext);
2754         mAppOpsService.publish(mContext);
2755         Slog.d("AppOps", "AppOpsService published");
2756         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2757     }
2758
2759     void onUserStoppedLocked(int userId) {
2760         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2761     }
2762
2763     public void initPowerManagement() {
2764         mStackSupervisor.initPowerManagement();
2765         mBatteryStatsService.initPowerManagement();
2766         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2767         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2768         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2769         mVoiceWakeLock.setReferenceCounted(false);
2770     }
2771
2772     @Override
2773     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2774             throws RemoteException {
2775         if (code == SYSPROPS_TRANSACTION) {
2776             // We need to tell all apps about the system property change.
2777             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2778             synchronized(this) {
2779                 final int NP = mProcessNames.getMap().size();
2780                 for (int ip=0; ip<NP; ip++) {
2781                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2782                     final int NA = apps.size();
2783                     for (int ia=0; ia<NA; ia++) {
2784                         ProcessRecord app = apps.valueAt(ia);
2785                         if (app.thread != null) {
2786                             procs.add(app.thread.asBinder());
2787                         }
2788                     }
2789                 }
2790             }
2791
2792             int N = procs.size();
2793             for (int i=0; i<N; i++) {
2794                 Parcel data2 = Parcel.obtain();
2795                 try {
2796                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2797                 } catch (RemoteException e) {
2798                 }
2799                 data2.recycle();
2800             }
2801         }
2802         try {
2803             return super.onTransact(code, data, reply, flags);
2804         } catch (RuntimeException e) {
2805             // The activity manager only throws security exceptions, so let's
2806             // log all others.
2807             if (!(e instanceof SecurityException)) {
2808                 Slog.wtf(TAG, "Activity Manager Crash", e);
2809             }
2810             throw e;
2811         }
2812     }
2813
2814     void updateCpuStats() {
2815         final long now = SystemClock.uptimeMillis();
2816         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2817             return;
2818         }
2819         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2820             synchronized (mProcessCpuThread) {
2821                 mProcessCpuThread.notify();
2822             }
2823         }
2824     }
2825
2826     void updateCpuStatsNow() {
2827         synchronized (mProcessCpuTracker) {
2828             mProcessCpuMutexFree.set(false);
2829             final long now = SystemClock.uptimeMillis();
2830             boolean haveNewCpuStats = false;
2831
2832             if (MONITOR_CPU_USAGE &&
2833                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2834                 mLastCpuTime.set(now);
2835                 mProcessCpuTracker.update();
2836                 if (mProcessCpuTracker.hasGoodLastStats()) {
2837                     haveNewCpuStats = true;
2838                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2839                     //Slog.i(TAG, "Total CPU usage: "
2840                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2841
2842                     // Slog the cpu usage if the property is set.
2843                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2844                         int user = mProcessCpuTracker.getLastUserTime();
2845                         int system = mProcessCpuTracker.getLastSystemTime();
2846                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2847                         int irq = mProcessCpuTracker.getLastIrqTime();
2848                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2849                         int idle = mProcessCpuTracker.getLastIdleTime();
2850
2851                         int total = user + system + iowait + irq + softIrq + idle;
2852                         if (total == 0) total = 1;
2853
2854                         EventLog.writeEvent(EventLogTags.CPU,
2855                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2856                                 (user * 100) / total,
2857                                 (system * 100) / total,
2858                                 (iowait * 100) / total,
2859                                 (irq * 100) / total,
2860                                 (softIrq * 100) / total);
2861                     }
2862                 }
2863             }
2864
2865             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2866             synchronized(bstats) {
2867                 synchronized(mPidsSelfLocked) {
2868                     if (haveNewCpuStats) {
2869                         if (bstats.startAddingCpuLocked()) {
2870                             int totalUTime = 0;
2871                             int totalSTime = 0;
2872                             final int N = mProcessCpuTracker.countStats();
2873                             for (int i=0; i<N; i++) {
2874                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2875                                 if (!st.working) {
2876                                     continue;
2877                                 }
2878                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2879                                 totalUTime += st.rel_utime;
2880                                 totalSTime += st.rel_stime;
2881                                 if (pr != null) {
2882                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2883                                     if (ps == null || !ps.isActive()) {
2884                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2885                                                 pr.info.uid, pr.processName);
2886                                     }
2887                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2889                                 } else {
2890                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2891                                     if (ps == null || !ps.isActive()) {
2892                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2893                                                 bstats.mapUid(st.uid), st.name);
2894                                     }
2895                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2896                                 }
2897                             }
2898                             final int userTime = mProcessCpuTracker.getLastUserTime();
2899                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2900                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2901                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2902                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2903                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2904                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2905                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2906                         }
2907                     }
2908                 }
2909
2910                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2911                     mLastWriteTime = now;
2912                     mBatteryStatsService.scheduleWriteToDisk();
2913                 }
2914             }
2915         }
2916     }
2917
2918     @Override
2919     public void batteryNeedsCpuUpdate() {
2920         updateCpuStatsNow();
2921     }
2922
2923     @Override
2924     public void batteryPowerChanged(boolean onBattery) {
2925         // When plugging in, update the CPU stats first before changing
2926         // the plug state.
2927         updateCpuStatsNow();
2928         synchronized (this) {
2929             synchronized(mPidsSelfLocked) {
2930                 mOnBattery = DEBUG_POWER ? true : onBattery;
2931             }
2932         }
2933     }
2934
2935     @Override
2936     public void batterySendBroadcast(Intent intent) {
2937         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2938                 AppOpsManager.OP_NONE, null, false, false,
2939                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2940     }
2941
2942     /**
2943      * Initialize the application bind args. These are passed to each
2944      * process when the bindApplication() IPC is sent to the process. They're
2945      * lazily setup to make sure the services are running when they're asked for.
2946      */
2947     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2948         // Isolated processes won't get this optimization, so that we don't
2949         // violate the rules about which services they have access to.
2950         if (isolated) {
2951             if (mIsolatedAppBindArgs == null) {
2952                 mIsolatedAppBindArgs = new HashMap<>();
2953                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2954             }
2955             return mIsolatedAppBindArgs;
2956         }
2957
2958         if (mAppBindArgs == null) {
2959             mAppBindArgs = new HashMap<>();
2960
2961             // Setup the application init args
2962             mAppBindArgs.put("package", ServiceManager.getService("package"));
2963             mAppBindArgs.put("window", ServiceManager.getService("window"));
2964             mAppBindArgs.put(Context.ALARM_SERVICE,
2965                     ServiceManager.getService(Context.ALARM_SERVICE));
2966         }
2967         return mAppBindArgs;
2968     }
2969
2970     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2971         if (r == null || mFocusedActivity == r) {
2972             return false;
2973         }
2974
2975         if (!r.isFocusable()) {
2976             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2977             return false;
2978         }
2979
2980         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2981
2982         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2983         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2984                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2985         mDoingSetFocusedActivity = true;
2986
2987         final ActivityRecord last = mFocusedActivity;
2988         mFocusedActivity = r;
2989         if (r.task.isApplicationTask()) {
2990             if (mCurAppTimeTracker != r.appTimeTracker) {
2991                 // We are switching app tracking.  Complete the current one.
2992                 if (mCurAppTimeTracker != null) {
2993                     mCurAppTimeTracker.stop();
2994                     mHandler.obtainMessage(
2995                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2996                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2997                     mCurAppTimeTracker = null;
2998                 }
2999                 if (r.appTimeTracker != null) {
3000                     mCurAppTimeTracker = r.appTimeTracker;
3001                     startTimeTrackingFocusedActivityLocked();
3002                 }
3003             } else {
3004                 startTimeTrackingFocusedActivityLocked();
3005             }
3006         } else {
3007             r.appTimeTracker = null;
3008         }
3009         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3010         // TODO: Probably not, because we don't want to resume voice on switching
3011         // back to this activity
3012         if (r.task.voiceInteractor != null) {
3013             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3014         } else {
3015             finishRunningVoiceLocked();
3016             IVoiceInteractionSession session;
3017             if (last != null && ((session = last.task.voiceSession) != null
3018                     || (session = last.voiceSession) != null)) {
3019                 // We had been in a voice interaction session, but now focused has
3020                 // move to something different.  Just finish the session, we can't
3021                 // return to it and retain the proper state and synchronization with
3022                 // the voice interaction service.
3023                 finishVoiceTask(session);
3024             }
3025         }
3026         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3027             mWindowManager.setFocusedApp(r.appToken, true);
3028         }
3029         applyUpdateLockStateLocked(r);
3030         applyUpdateVrModeLocked(r);
3031         if (mFocusedActivity.userId != mLastFocusedUserId) {
3032             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3033             mHandler.obtainMessage(
3034                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3035             mLastFocusedUserId = mFocusedActivity.userId;
3036         }
3037
3038         // Log a warning if the focused app is changed during the process. This could
3039         // indicate a problem of the focus setting logic!
3040         if (mFocusedActivity != r) Slog.w(TAG,
3041                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3042         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3043
3044         EventLogTags.writeAmFocusedActivity(
3045                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3046                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3047                 reason);
3048         return true;
3049     }
3050
3051     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3052         if (mFocusedActivity != goingAway) {
3053             return;
3054         }
3055
3056         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3057         if (focusedStack != null) {
3058             final ActivityRecord top = focusedStack.topActivity();
3059             if (top != null && top.userId != mLastFocusedUserId) {
3060                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3061                 mHandler.sendMessage(
3062                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3063                 mLastFocusedUserId = top.userId;
3064             }
3065         }
3066
3067         // Try to move focus to another activity if possible.
3068         if (setFocusedActivityLocked(
3069                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3070             return;
3071         }
3072
3073         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3074                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3075         mFocusedActivity = null;
3076         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3077     }
3078
3079     @Override
3080     public void setFocusedStack(int stackId) {
3081         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3082         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3083         final long callingId = Binder.clearCallingIdentity();
3084         try {
3085             synchronized (this) {
3086                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3087                 if (stack == null) {
3088                     return;
3089                 }
3090                 final ActivityRecord r = stack.topRunningActivityLocked();
3091                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3092                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3093                 }
3094             }
3095         } finally {
3096             Binder.restoreCallingIdentity(callingId);
3097         }
3098     }
3099
3100     @Override
3101     public void setFocusedTask(int taskId) {
3102         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3103         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3104         final long callingId = Binder.clearCallingIdentity();
3105         try {
3106             synchronized (this) {
3107                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3108                 if (task == null) {
3109                     return;
3110                 }
3111                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3112                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3113                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3114                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3115                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3116                                 "setFocusedTask", ANIMATE);
3117                     }
3118                     return;
3119                 }
3120                 final ActivityRecord r = task.topRunningActivityLocked();
3121                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3122                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3123                 }
3124             }
3125         } finally {
3126             Binder.restoreCallingIdentity(callingId);
3127         }
3128     }
3129
3130     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3131     @Override
3132     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3133         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3134         synchronized (this) {
3135             if (listener != null) {
3136                 mTaskStackListeners.register(listener);
3137             }
3138         }
3139     }
3140
3141     @Override
3142     public void notifyActivityDrawn(IBinder token) {
3143         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3144         synchronized (this) {
3145             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3146             if (r != null) {
3147                 r.task.stack.notifyActivityDrawnLocked(r);
3148             }
3149         }
3150     }
3151
3152     final void applyUpdateLockStateLocked(ActivityRecord r) {
3153         // Modifications to the UpdateLock state are done on our handler, outside
3154         // the activity manager's locks.  The new state is determined based on the
3155         // state *now* of the relevant activity record.  The object is passed to
3156         // the handler solely for logging detail, not to be consulted/modified.
3157         final boolean nextState = r != null && r.immersive;
3158         mHandler.sendMessage(
3159                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3160     }
3161
3162     final void applyUpdateVrModeLocked(ActivityRecord r) {
3163         mHandler.sendMessage(
3164                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3165     }
3166
3167     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3168         mHandler.sendMessage(
3169                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3170     }
3171
3172     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3173             ComponentName callingPackage, boolean immediate) {
3174         VrManagerInternal vrService =
3175                 LocalServices.getService(VrManagerInternal.class);
3176         if (immediate) {
3177             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3178         } else {
3179             vrService.setVrMode(enabled, packageName, userId, callingPackage);
3180         }
3181     }
3182
3183     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184         Message msg = Message.obtain();
3185         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186         msg.obj = r.task.askedCompatMode ? null : r;
3187         mUiHandler.sendMessage(msg);
3188     }
3189
3190     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193             final Message msg = Message.obtain();
3194             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3195             msg.obj = r;
3196             mUiHandler.sendMessage(msg);
3197         }
3198     }
3199
3200     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201             String what, Object obj, ProcessRecord srcApp) {
3202         app.lastActivityTime = now;
3203
3204         if (app.activities.size() > 0) {
3205             // Don't want to touch dependent processes that are hosting activities.
3206             return index;
3207         }
3208
3209         int lrui = mLruProcesses.lastIndexOf(app);
3210         if (lrui < 0) {
3211             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212                     + what + " " + obj + " from " + srcApp);
3213             return index;
3214         }
3215
3216         if (lrui >= index) {
3217             // Don't want to cause this to move dependent processes *back* in the
3218             // list as if they were less frequently used.
3219             return index;
3220         }
3221
3222         if (lrui >= mLruProcessActivityStart) {
3223             // Don't want to touch dependent processes that are hosting activities.
3224             return index;
3225         }
3226
3227         mLruProcesses.remove(lrui);
3228         if (index > 0) {
3229             index--;
3230         }
3231         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232                 + " in LRU list: " + app);
3233         mLruProcesses.add(index, app);
3234         return index;
3235     }
3236
3237     static void killProcessGroup(int uid, int pid) {
3238         if (sKillHandler != null) {
3239             sKillHandler.sendMessage(
3240                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3241         } else {
3242             Slog.w(TAG, "Asked to kill process group before system bringup!");
3243             Process.killProcessGroup(uid, pid);
3244         }
3245     }
3246
3247     final void removeLruProcessLocked(ProcessRecord app) {
3248         int lrui = mLruProcesses.lastIndexOf(app);
3249         if (lrui >= 0) {
3250             if (!app.killed) {
3251                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252                 Process.killProcessQuiet(app.pid);
3253                 killProcessGroup(app.uid, app.pid);
3254             }
3255             if (lrui <= mLruProcessActivityStart) {
3256                 mLruProcessActivityStart--;
3257             }
3258             if (lrui <= mLruProcessServiceStart) {
3259                 mLruProcessServiceStart--;
3260             }
3261             mLruProcesses.remove(lrui);
3262         }
3263     }
3264
3265     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266             ProcessRecord client) {
3267         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268                 || app.treatLikeActivity;
3269         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270         if (!activityChange && hasActivity) {
3271             // The process has activities, so we are only allowing activity-based adjustments
3272             // to move it.  It should be kept in the front of the list with other
3273             // processes that have activities, and we don't want those to change their
3274             // order except due to activity operations.
3275             return;
3276         }
3277
3278         mLruSeq++;
3279         final long now = SystemClock.uptimeMillis();
3280         app.lastActivityTime = now;
3281
3282         // First a quick reject: if the app is already at the position we will
3283         // put it, then there is nothing to do.
3284         if (hasActivity) {
3285             final int N = mLruProcesses.size();
3286             if (N > 0 && mLruProcesses.get(N-1) == app) {
3287                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3288                 return;
3289             }
3290         } else {
3291             if (mLruProcessServiceStart > 0
3292                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3294                 return;
3295             }
3296         }
3297
3298         int lrui = mLruProcesses.lastIndexOf(app);
3299
3300         if (app.persistent && lrui >= 0) {
3301             // We don't care about the position of persistent processes, as long as
3302             // they are in the list.
3303             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3304             return;
3305         }
3306
3307         /* In progress: compute new position first, so we can avoid doing work
3308            if the process is not actually going to move.  Not yet working.
3309         int addIndex;
3310         int nextIndex;
3311         boolean inActivity = false, inService = false;
3312         if (hasActivity) {
3313             // Process has activities, put it at the very tipsy-top.
3314             addIndex = mLruProcesses.size();
3315             nextIndex = mLruProcessServiceStart;
3316             inActivity = true;
3317         } else if (hasService) {
3318             // Process has services, put it at the top of the service list.
3319             addIndex = mLruProcessActivityStart;
3320             nextIndex = mLruProcessServiceStart;
3321             inActivity = true;
3322             inService = true;
3323         } else  {
3324             // Process not otherwise of interest, it goes to the top of the non-service area.
3325             addIndex = mLruProcessServiceStart;
3326             if (client != null) {
3327                 int clientIndex = mLruProcesses.lastIndexOf(client);
3328                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3329                         + app);
3330                 if (clientIndex >= 0 && addIndex > clientIndex) {
3331                     addIndex = clientIndex;
3332                 }
3333             }
3334             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3335         }
3336
3337         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338                 + mLruProcessActivityStart + "): " + app);
3339         */
3340
3341         if (lrui >= 0) {
3342             if (lrui < mLruProcessActivityStart) {
3343                 mLruProcessActivityStart--;
3344             }
3345             if (lrui < mLruProcessServiceStart) {
3346                 mLruProcessServiceStart--;
3347             }
3348             /*
3349             if (addIndex > lrui) {
3350                 addIndex--;
3351             }
3352             if (nextIndex > lrui) {
3353                 nextIndex--;
3354             }
3355             */
3356             mLruProcesses.remove(lrui);
3357         }
3358
3359         /*
3360         mLruProcesses.add(addIndex, app);
3361         if (inActivity) {
3362             mLruProcessActivityStart++;
3363         }
3364         if (inService) {
3365             mLruProcessActivityStart++;
3366         }
3367         */
3368
3369         int nextIndex;
3370         if (hasActivity) {
3371             final int N = mLruProcesses.size();
3372             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373                 // Process doesn't have activities, but has clients with
3374                 // activities...  move it up, but one below the top (the top
3375                 // should always have a real activity).
3376                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377                         "Adding to second-top of LRU activity list: " + app);
3378                 mLruProcesses.add(N - 1, app);
3379                 // To keep it from spamming the LRU list (by making a bunch of clients),
3380                 // we will push down any other entries owned by the app.
3381                 final int uid = app.info.uid;
3382                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383                     ProcessRecord subProc = mLruProcesses.get(i);
3384                     if (subProc.info.uid == uid) {
3385                         // We want to push this one down the list.  If the process after
3386                         // it is for the same uid, however, don't do so, because we don't
3387                         // want them internally to be re-ordered.
3388                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3389                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3390                                     "Pushing uid " + uid + " swapping at " + i + ": "
3391                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392                             ProcessRecord tmp = mLruProcesses.get(i);
3393                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394                             mLruProcesses.set(i - 1, tmp);
3395                             i--;
3396                         }
3397                     } else {
3398                         // A gap, we can stop here.
3399                         break;
3400                     }
3401                 }
3402             } else {
3403                 // Process has activities, put it at the very tipsy-top.
3404                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405                 mLruProcesses.add(app);
3406             }
3407             nextIndex = mLruProcessServiceStart;
3408         } else if (hasService) {
3409             // Process has services, put it at the top of the service list.
3410             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411             mLruProcesses.add(mLruProcessActivityStart, app);
3412             nextIndex = mLruProcessServiceStart;
3413             mLruProcessActivityStart++;
3414         } else  {
3415             // Process not otherwise of interest, it goes to the top of the non-service area.
3416             int index = mLruProcessServiceStart;
3417             if (client != null) {
3418                 // If there is a client, don't allow the process to be moved up higher
3419                 // in the list than that client.
3420                 int clientIndex = mLruProcesses.lastIndexOf(client);
3421                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422                         + " when updating " + app);
3423                 if (clientIndex <= lrui) {
3424                     // Don't allow the client index restriction to push it down farther in the
3425                     // list than it already is.
3426                     clientIndex = lrui;
3427                 }
3428                 if (clientIndex >= 0 && index > clientIndex) {
3429                     index = clientIndex;
3430                 }
3431             }
3432             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433             mLruProcesses.add(index, app);
3434             nextIndex = index-1;
3435             mLruProcessActivityStart++;
3436             mLruProcessServiceStart++;
3437         }
3438
3439         // If the app is currently using a content provider or service,
3440         // bump those processes as well.
3441         for (int j=app.connections.size()-1; j>=0; j--) {
3442             ConnectionRecord cr = app.connections.valueAt(j);
3443             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444                     && cr.binding.service.app != null
3445                     && cr.binding.service.app.lruSeq != mLruSeq
3446                     && !cr.binding.service.app.persistent) {
3447                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448                         "service connection", cr, app);
3449             }
3450         }
3451         for (int j=app.conProviders.size()-1; j>=0; j--) {
3452             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455                         "provider reference", cpr, app);
3456             }
3457         }
3458     }
3459
3460     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461         if (uid == Process.SYSTEM_UID) {
3462             // The system gets to run in any process.  If there are multiple
3463             // processes with the same uid, just pick the first (this
3464             // should never happen).
3465             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466             if (procs == null) return null;
3467             final int procCount = procs.size();
3468             for (int i = 0; i < procCount; i++) {
3469                 final int procUid = procs.keyAt(i);
3470                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471                     // Don't use an app process or different user process for system component.
3472                     continue;
3473                 }
3474                 return procs.valueAt(i);
3475             }
3476         }
3477         ProcessRecord proc = mProcessNames.get(processName, uid);
3478         if (false && proc != null && !keepIfLarge
3479                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480                 && proc.lastCachedPss >= 4000) {
3481             // Turn this condition on to cause killing to happen regularly, for testing.
3482             if (proc.baseProcessTracker != null) {
3483                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3484             }
3485             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486         } else if (proc != null && !keepIfLarge
3487                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491                 if (proc.baseProcessTracker != null) {
3492                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3493                 }
3494                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3495             }
3496         }
3497         return proc;
3498     }
3499
3500     void notifyPackageUse(String packageName, int reason) {
3501         IPackageManager pm = AppGlobals.getPackageManager();
3502         try {
3503             pm.notifyPackageUse(packageName, reason);
3504         } catch (RemoteException e) {
3505         }
3506     }
3507
3508     boolean isNextTransitionForward() {
3509         int transit = mWindowManager.getPendingAppTransition();
3510         return transit == TRANSIT_ACTIVITY_OPEN
3511                 || transit == TRANSIT_TASK_OPEN
3512                 || transit == TRANSIT_TASK_TO_FRONT;
3513     }
3514
3515     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516             String processName, String abiOverride, int uid, Runnable crashHandler) {
3517         synchronized(this) {
3518             ApplicationInfo info = new ApplicationInfo();
3519             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520             // For isolated processes, the former contains the parent's uid and the latter the
3521             // actual uid of the isolated process.
3522             // In the special case introduced by this method (which is, starting an isolated
3523             // process directly from the SystemServer without an actual parent app process) the
3524             // closest thing to a parent's uid is SYSTEM_UID.
3525             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526             // the |isolated| logic in the ProcessRecord constructor.
3527             info.uid = Process.SYSTEM_UID;
3528             info.processName = processName;
3529             info.className = entryPoint;
3530             info.packageName = "android";
3531             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3533                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3535                     crashHandler);
3536             return proc != null ? proc.pid : 0;
3537         }
3538     }
3539
3540     final ProcessRecord startProcessLocked(String processName,
3541             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543             boolean isolated, boolean keepIfLarge) {
3544         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547                 null /* crashHandler */);
3548     }
3549
3550     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554         long startTime = SystemClock.elapsedRealtime();
3555         ProcessRecord app;
3556         if (!isolated) {
3557             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558             checkTime(startTime, "startProcess: after getProcessRecord");
3559
3560             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561                 // If we are in the background, then check to see if this process
3562                 // is bad.  If so, we will just silently fail.
3563                 if (mAppErrors.isBadProcessLocked(info)) {
3564                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565                             + "/" + info.processName);
3566                     return null;
3567                 }
3568             } else {
3569                 // When the user is explicitly starting a process, then clear its
3570                 // crash count so that we won't make it bad until they see at
3571                 // least one crash dialog again, and make the process good again
3572                 // if it had been bad.
3573                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574                         + "/" + info.processName);
3575                 mAppErrors.resetProcessCrashTimeLocked(info);
3576                 if (mAppErrors.isBadProcessLocked(info)) {
3577                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578                             UserHandle.getUserId(info.uid), info.uid,
3579                             info.processName);
3580                     mAppErrors.clearBadProcessLocked(info);
3581                     if (app != null) {
3582                         app.bad = false;
3583                     }
3584                 }
3585             }
3586         } else {
3587             // If this is an isolated process, it can't re-use an existing process.
3588             app = null;
3589         }
3590
3591         // app launch boost for big.little configurations
3592         // use cpusets to migrate freshly launched tasks to big cores
3593         nativeMigrateToBoost();
3594         mIsBoosted = true;
3595         mBoostStartTime = SystemClock.uptimeMillis();
3596         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3598
3599         // We don't have to do anything more if:
3600         // (1) There is an existing application record; and
3601         // (2) The caller doesn't think it is dead, OR there is no thread
3602         //     object attached to it so we know it couldn't have crashed; and
3603         // (3) There is a pid assigned to it, so it is either starting or
3604         //     already running.
3605         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607                 + " thread=" + (app != null ? app.thread : null)
3608                 + " pid=" + (app != null ? app.pid : -1));
3609         if (app != null && app.pid > 0) {
3610             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611                 // We already have the app running, or are waiting for it to
3612                 // come up (we have a pid but not yet its thread), so keep it.
3613                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614                 // If this is a new package in the process, add the package to the list
3615                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616                 checkTime(startTime, "startProcess: done, added package to proc");
3617                 return app;
3618             }
3619
3620             // An application record is attached to a previous process,
3621             // clean it up now.
3622             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623             checkTime(startTime, "startProcess: bad proc running, killing");
3624             killProcessGroup(app.uid, app.pid);
3625             handleAppDiedLocked(app, true, true);
3626             checkTime(startTime, "startProcess: done killing old proc");
3627         }
3628
3629         String hostingNameStr = hostingName != null
3630                 ? hostingName.flattenToShortString() : null;
3631
3632         if (app == null) {
3633             checkTime(startTime, "startProcess: creating new process record");
3634             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3635             if (app == null) {
3636                 Slog.w(TAG, "Failed making new process record for "
3637                         + processName + "/" + info.uid + " isolated=" + isolated);
3638                 return null;
3639             }
3640             app.crashHandler = crashHandler;
3641             checkTime(startTime, "startProcess: done creating new process record");
3642         } else {
3643             // If this is a new package in the process, add the package to the list
3644             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645             checkTime(startTime, "startProcess: added package to existing proc");
3646         }
3647
3648         // If the system is not ready yet, then hold off on starting this
3649         // process until it is.
3650         if (!mProcessesReady
3651                 && !isAllowedWhileBooting(info)
3652                 && !allowWhileBooting) {
3653             if (!mProcessesOnHold.contains(app)) {
3654                 mProcessesOnHold.add(app);
3655             }
3656             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657                     "System not ready, putting on hold: " + app);
3658             checkTime(startTime, "startProcess: returning with proc on hold");
3659             return app;
3660         }
3661
3662         checkTime(startTime, "startProcess: stepping in to startProcess");
3663         startProcessLocked(
3664                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665         checkTime(startTime, "startProcess: done starting proc!");
3666         return (app.pid != 0) ? app : null;
3667     }
3668
3669     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3671     }
3672
3673     private final void startProcessLocked(ProcessRecord app,
3674             String hostingType, String hostingNameStr) {
3675         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676                 null /* entryPoint */, null /* entryPointArgs */);
3677     }
3678
3679     private final void startProcessLocked(ProcessRecord app, String hostingType,
3680             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681         long startTime = SystemClock.elapsedRealtime();
3682         if (app.pid > 0 && app.pid != MY_PID) {
3683             checkTime(startTime, "startProcess: removing from pids map");
3684             synchronized (mPidsSelfLocked) {
3685                 mPidsSelfLocked.remove(app.pid);
3686                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3687             }
3688             checkTime(startTime, "startProcess: done removing from pids map");
3689             app.setPid(0);
3690         }
3691
3692         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693                 "startProcessLocked removing on hold: " + app);
3694         mProcessesOnHold.remove(app);
3695
3696         checkTime(startTime, "startProcess: starting to update cpu stats");
3697         updateCpuStats();
3698         checkTime(startTime, "startProcess: done updating cpu stats");
3699
3700         try {
3701             try {
3702                 final int userId = UserHandle.getUserId(app.uid);
3703                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704             } catch (RemoteException e) {
3705                 throw e.rethrowAsRuntimeException();
3706             }
3707
3708             int uid = app.uid;
3709             int[] gids = null;
3710             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711             if (!app.isolated) {
3712                 int[] permGids = null;
3713                 try {
3714                     checkTime(startTime, "startProcess: getting gids from package manager");
3715                     final IPackageManager pm = AppGlobals.getPackageManager();
3716                     permGids = pm.getPackageGids(app.info.packageName,
3717                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3719                             MountServiceInternal.class);
3720                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721                             app.info.packageName);
3722                 } catch (RemoteException e) {
3723                     throw e.rethrowAsRuntimeException();
3724                 }
3725
3726                 /*
3727                  * Add shared application and profile GIDs so applications can share some
3728                  * resources like shared libraries and access user-wide resources
3729                  */
3730                 if (ArrayUtils.isEmpty(permGids)) {
3731                     gids = new int[2];
3732                 } else {
3733                     gids = new int[permGids.length + 2];
3734                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3735                 }
3736                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3738             }
3739             checkTime(startTime, "startProcess: building args");
3740             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742                         && mTopComponent != null
3743                         && app.processName.equals(mTopComponent.getPackageName())) {
3744                     uid = 0;
3745                 }
3746                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3748                     uid = 0;
3749                 }
3750             }
3751             int debugFlags = 0;
3752             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754                 // Also turn on CheckJNI for debuggable apps. It's quite
3755                 // awkward to turn on otherwise.
3756                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3757             }
3758             // Run the app in safe mode if its manifest requests so or the
3759             // system is booted in safe mode.
3760             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761                 mSafeMode == true) {
3762                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3763             }
3764             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3766             }
3767             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768             if ("true".equals(genDebugInfoProperty)) {
3769                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3770             }
3771             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3773             }
3774             if ("1".equals(SystemProperties.get("debug.assert"))) {
3775                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3776             }
3777             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778                 // Enable all debug flags required by the native debugger.
3779                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3780                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3782                 mNativeDebuggingApp = null;
3783             }
3784
3785             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786             if (requiredAbi == null) {
3787                 requiredAbi = Build.SUPPORTED_ABIS[0];
3788             }
3789
3790             String instructionSet = null;
3791             if (app.info.primaryCpuAbi != null) {
3792                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3793             }
3794
3795             app.gids = gids;
3796             app.requiredAbi = requiredAbi;
3797             app.instructionSet = instructionSet;
3798
3799             // Start the process.  It will either succeed and return a result containing
3800             // the PID of the new process, or else throw a RuntimeException.
3801             boolean isActivityProcess = (entryPoint == null);
3802             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3804                     app.processName);
3805             checkTime(startTime, "startProcess: asking zygote to start proc");
3806             Process.ProcessStartResult startResult = Process.start(entryPoint,
3807                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3808                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809                     app.info.dataDir, entryPointArgs);
3810             checkTime(startTime, "startProcess: returned from zygote!");
3811             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3812
3813             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814             checkTime(startTime, "startProcess: done updating battery stats");
3815
3816             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817                     UserHandle.getUserId(uid), startResult.pid, uid,
3818                     app.processName, hostingType,
3819                     hostingNameStr != null ? hostingNameStr : "");
3820
3821             try {
3822                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3824             } catch (RemoteException ex) {
3825                 // Ignore
3826             }
3827
3828             if (app.persistent) {
3829                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3830             }
3831
3832             checkTime(startTime, "startProcess: building log message");
3833             StringBuilder buf = mStringBuilder;
3834             buf.setLength(0);
3835             buf.append("Start proc ");
3836             buf.append(startResult.pid);
3837             buf.append(':');
3838             buf.append(app.processName);
3839             buf.append('/');
3840             UserHandle.formatUid(buf, uid);
3841             if (!isActivityProcess) {
3842                 buf.append(" [");
3843                 buf.append(entryPoint);
3844                 buf.append("]");
3845             }
3846             buf.append(" for ");
3847             buf.append(hostingType);
3848             if (hostingNameStr != null) {
3849                 buf.append(" ");
3850                 buf.append(hostingNameStr);
3851             }
3852             Slog.i(TAG, buf.toString());
3853             app.setPid(startResult.pid);
3854             app.usingWrapper = startResult.usingWrapper;
3855             app.removed = false;
3856             app.killed = false;
3857             app.killedByAm = false;
3858             checkTime(startTime, "startProcess: starting to update pids map");
3859             ProcessRecord oldApp;
3860             synchronized (mPidsSelfLocked) {
3861                 oldApp = mPidsSelfLocked.get(startResult.pid);
3862             }
3863             // If there is already an app occupying that pid that hasn't been cleaned up
3864             if (oldApp != null && !app.isolated) {
3865                 // Clean up anything relating to this pid first
3866                 Slog.w(TAG, "Reusing pid " + startResult.pid
3867                         + " while app is still mapped to it");
3868                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869                         true /*replacingPid*/);
3870             }
3871             synchronized (mPidsSelfLocked) {
3872                 this.mPidsSelfLocked.put(startResult.pid, app);
3873                 if (isActivityProcess) {
3874                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3875                     msg.obj = app;
3876                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3878                 }
3879             }
3880             checkTime(startTime, "startProcess: done updating pids map");
3881         } catch (RuntimeException e) {
3882             Slog.e(TAG, "Failure starting process " + app.processName, e);
3883
3884             // Something went very wrong while trying to start this process; one
3885             // common case is when the package is frozen due to an active
3886             // upgrade. To recover, clean up any active bookkeeping related to
3887             // starting this process. (We already invoked this method once when
3888             // the package was initially frozen through KILL_APPLICATION_MSG, so
3889             // it doesn't hurt to use it again.)
3890             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3892         }
3893     }
3894
3895     void updateUsageStats(ActivityRecord component, boolean resumed) {
3896         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897                 "updateUsageStats: comp=" + component + "res=" + resumed);
3898         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3899         if (resumed) {
3900             if (mUsageStatsService != null) {
3901                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3903             }
3904             synchronized (stats) {
3905                 stats.noteActivityResumedLocked(component.app.uid);
3906             }
3907         } else {
3908             if (mUsageStatsService != null) {
3909                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3911             }
3912             synchronized (stats) {
3913                 stats.noteActivityPausedLocked(component.app.uid);
3914             }
3915         }
3916     }
3917
3918     Intent getHomeIntent() {
3919         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920         intent.setComponent(mTopComponent);
3921         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923             intent.addCategory(Intent.CATEGORY_HOME);
3924         }
3925         return intent;
3926     }
3927
3928     boolean startHomeActivityLocked(int userId, String reason) {
3929         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930                 && mTopAction == null) {
3931             // We are running in factory test mode, but unable to find
3932             // the factory test app, so just sit around displaying the
3933             // error message and don't try to start anything.
3934             return false;
3935         }
3936         Intent intent = getHomeIntent();
3937         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938         if (aInfo != null) {
3939             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940             // Don't do this if the home app is currently being
3941             // instrumented.
3942             aInfo = new ActivityInfo(aInfo);
3943             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945                     aInfo.applicationInfo.uid, true);
3946             if (app == null || app.instrumentationClass == null) {
3947                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3949             }
3950         } else {
3951             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3952         }
3953
3954         return true;
3955     }
3956
3957     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958         ActivityInfo ai = null;
3959         ComponentName comp = intent.getComponent();
3960         try {
3961             if (comp != null) {
3962                 // Factory test.
3963                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3964             } else {
3965                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3966                         intent,
3967                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3968                         flags, userId);
3969
3970                 if (info != null) {
3971                     ai = info.activityInfo;
3972                 }
3973             }
3974         } catch (RemoteException e) {
3975             // ignore
3976         }
3977
3978         return ai;
3979     }
3980
3981     /**
3982      * Starts the "new version setup screen" if appropriate.
3983      */
3984     void startSetupActivityLocked() {
3985         // Only do this once per boot.
3986         if (mCheckedForSetup) {
3987             return;
3988         }
3989
3990         // We will show this screen if the current one is a different
3991         // version than the last one shown, and we are not running in
3992         // low-level factory test mode.
3993         final ContentResolver resolver = mContext.getContentResolver();
3994         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995                 Settings.Global.getInt(resolver,
3996                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997             mCheckedForSetup = true;
3998
3999             // See if we should be showing the platform update setup UI.
4000             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003             if (!ris.isEmpty()) {
4004                 final ResolveInfo ri = ris.get(0);
4005                 String vers = ri.activityInfo.metaData != null
4006                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4007                         : null;
4008                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4010                             Intent.METADATA_SETUP_VERSION);
4011                 }
4012                 String lastVers = Settings.Secure.getString(
4013                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014                 if (vers != null && !vers.equals(lastVers)) {
4015                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016                     intent.setComponent(new ComponentName(
4017                             ri.activityInfo.packageName, ri.activityInfo.name));
4018                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020                             null, 0, 0, 0, null, false, false, null, null, null);
4021                 }
4022             }
4023         }
4024     }
4025
4026     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4028     }
4029
4030     void enforceNotIsolatedCaller(String caller) {
4031         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032             throw new SecurityException("Isolated process not allowed to call " + caller);
4033         }
4034     }
4035
4036     void enforceShellRestriction(String restriction, int userHandle) {
4037         if (Binder.getCallingUid() == Process.SHELL_UID) {
4038             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039                 throw new SecurityException("Shell does not have permission to access user "
4040                         + userHandle);
4041             }
4042         }
4043     }
4044
4045     @Override
4046     public int getFrontActivityScreenCompatMode() {
4047         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048         synchronized (this) {
4049             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4050         }
4051     }
4052
4053     @Override
4054     public void setFrontActivityScreenCompatMode(int mode) {
4055         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056                 "setFrontActivityScreenCompatMode");
4057         synchronized (this) {
4058             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4059         }
4060     }
4061
4062     @Override
4063     public int getPackageScreenCompatMode(String packageName) {
4064         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065         synchronized (this) {
4066             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4067         }
4068     }
4069
4070     @Override
4071     public void setPackageScreenCompatMode(String packageName, int mode) {
4072         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073                 "setPackageScreenCompatMode");
4074         synchronized (this) {
4075             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4076         }
4077     }
4078
4079     @Override
4080     public boolean getPackageAskScreenCompat(String packageName) {
4081         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082         synchronized (this) {
4083             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4084         }
4085     }
4086
4087     @Override
4088     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090                 "setPackageAskScreenCompat");
4091         synchronized (this) {
4092             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4093         }
4094     }
4095
4096     private boolean hasUsageStatsPermission(String callingPackage) {
4097         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098                 Binder.getCallingUid(), callingPackage);
4099         if (mode == AppOpsManager.MODE_DEFAULT) {
4100             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101                     == PackageManager.PERMISSION_GRANTED;
4102         }
4103         return mode == AppOpsManager.MODE_ALLOWED;
4104     }
4105
4106     @Override
4107     public int getPackageProcessState(String packageName, String callingPackage) {
4108         if (!hasUsageStatsPermission(callingPackage)) {
4109             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110                     "getPackageProcessState");
4111         }
4112
4113         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114         synchronized (this) {
4115             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116                 final ProcessRecord proc = mLruProcesses.get(i);
4117                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118                         || procState > proc.setProcState) {
4119                     boolean found = false;
4120                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4122                             procState = proc.setProcState;
4123                             found = true;
4124                         }
4125                     }
4126                     if (proc.pkgDeps != null && !found) {
4127                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129                                 procState = proc.setProcState;
4130                                 break;
4131                             }
4132                         }
4133                     }
4134                 }
4135             }
4136         }
4137         return procState;
4138     }
4139
4140     @Override
4141     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142         synchronized (this) {
4143             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4144             if (app == null) {
4145                 return false;
4146             }
4147             if (app.trimMemoryLevel < level && app.thread != null &&
4148                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4150                 try {
4151                     app.thread.scheduleTrimMemory(level);
4152                     app.trimMemoryLevel = level;
4153                     return true;
4154                 } catch (RemoteException e) {
4155                     // Fallthrough to failure case.
4156                 }
4157             }
4158         }
4159         return false;
4160     }
4161
4162     private void dispatchProcessesChanged() {
4163         int N;
4164         synchronized (this) {
4165             N = mPendingProcessChanges.size();
4166             if (mActiveProcessChanges.length < N) {
4167                 mActiveProcessChanges = new ProcessChangeItem[N];
4168             }
4169             mPendingProcessChanges.toArray(mActiveProcessChanges);
4170             mPendingProcessChanges.clear();
4171             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172                     "*** Delivering " + N + " process changes");
4173         }
4174
4175         int i = mProcessObservers.beginBroadcast();
4176         while (i > 0) {
4177             i--;
4178             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179             if (observer != null) {
4180                 try {
4181                     for (int j=0; j<N; j++) {
4182                         ProcessChangeItem item = mActiveProcessChanges[j];
4183                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186                                     + item.uid + ": " + item.foregroundActivities);
4187                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188                                     item.foregroundActivities);
4189                         }
4190                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193                                     + ": " + item.processState);
4194                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4195                         }
4196                     }
4197                 } catch (RemoteException e) {
4198                 }
4199             }
4200         }
4201         mProcessObservers.finishBroadcast();
4202
4203         synchronized (this) {
4204             for (int j=0; j<N; j++) {
4205                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4206             }
4207         }
4208     }
4209
4210     private void dispatchProcessDied(int pid, int uid) {
4211         int i = mProcessObservers.beginBroadcast();
4212         while (i > 0) {
4213             i--;
4214             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215             if (observer != null) {
4216                 try {
4217                     observer.onProcessDied(pid, uid);
4218                 } catch (RemoteException e) {
4219                 }
4220             }
4221         }
4222         mProcessObservers.finishBroadcast();
4223     }
4224
4225     private void dispatchUidsChanged() {
4226         int N;
4227         synchronized (this) {
4228             N = mPendingUidChanges.size();
4229             if (mActiveUidChanges.length < N) {
4230                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4231             }
4232             for (int i=0; i<N; i++) {
4233                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234                 mActiveUidChanges[i] = change;
4235                 if (change.uidRecord != null) {
4236                     change.uidRecord.pendingChange = null;
4237                     change.uidRecord = null;
4238                 }
4239             }
4240             mPendingUidChanges.clear();
4241             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242                     "*** Delivering " + N + " uid changes");
4243         }
4244
4245         if (mLocalPowerManager != null) {
4246             for (int j=0; j<N; j++) {
4247                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248                 if (item.change == UidRecord.CHANGE_GONE
4249                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250                     mLocalPowerManager.uidGone(item.uid);
4251                 } else {
4252                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4253                 }
4254             }
4255         }
4256
4257         int i = mUidObservers.beginBroadcast();
4258         while (i > 0) {
4259             i--;
4260             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262             if (observer != null) {
4263                 try {
4264                     for (int j=0; j<N; j++) {
4265                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4266                         final int change = item.change;
4267                         UidRecord validateUid = null;
4268                         if (VALIDATE_UID_STATES && i == 0) {
4269                             validateUid = mValidateUids.get(item.uid);
4270                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4271                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4272                                 validateUid = new UidRecord(item.uid);
4273                                 mValidateUids.put(item.uid, validateUid);
4274                             }
4275                         }
4276                         if (change == UidRecord.CHANGE_IDLE
4277                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4278                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280                                         "UID idle uid=" + item.uid);
4281                                 observer.onUidIdle(item.uid);
4282                             }
4283                             if (VALIDATE_UID_STATES && i == 0) {
4284                                 if (validateUid != null) {
4285                                     validateUid.idle = true;
4286                                 }
4287                             }
4288                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4289                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291                                         "UID active uid=" + item.uid);
4292                                 observer.onUidActive(item.uid);
4293                             }
4294                             if (VALIDATE_UID_STATES && i == 0) {
4295                                 validateUid.idle = false;
4296                             }
4297                         }
4298                         if (change == UidRecord.CHANGE_GONE
4299                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4300                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302                                         "UID gone uid=" + item.uid);
4303                                 observer.onUidGone(item.uid);
4304                             }
4305                             if (VALIDATE_UID_STATES && i == 0) {
4306                                 if (validateUid != null) {
4307                                     mValidateUids.remove(item.uid);
4308                                 }
4309                             }
4310                         } else {
4311                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313                                         "UID CHANGED uid=" + item.uid
4314                                                 + ": " + item.processState);
4315                                 observer.onUidStateChanged(item.uid, item.processState);
4316                             }
4317                             if (VALIDATE_UID_STATES && i == 0) {
4318                                 validateUid.curProcState = validateUid.setProcState
4319                                         = item.processState;
4320                             }
4321                         }
4322                     }
4323                 } catch (RemoteException e) {
4324                 }
4325             }
4326         }
4327         mUidObservers.finishBroadcast();
4328
4329         synchronized (this) {
4330             for (int j=0; j<N; j++) {
4331                 mAvailUidChanges.add(mActiveUidChanges[j]);
4332             }
4333         }
4334     }
4335
4336     @Override
4337     public final int startActivity(IApplicationThread caller, String callingPackage,
4338             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342                 UserHandle.getCallingUserId());
4343     }
4344
4345     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4350
4351         // TODO: Switch to user app stacks here.
4352         String mimeType = intent.getType();
4353         final Uri data = intent.getData();
4354         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355             mimeType = getProviderMimeType(data, userId);
4356         }
4357         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4358
4359         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361                 null, 0, 0, null, null, null, null, false, userId, container, null);
4362     }
4363
4364     @Override
4365     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368         enforceNotIsolatedCaller("startActivity");
4369         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371         // TODO: Switch to user app stacks here.
4372         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374                 profilerInfo, null, null, bOptions, false, userId, null, null);
4375     }
4376
4377     @Override
4378     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4381             int userId) {
4382
4383         // This is very dangerous -- it allows you to perform a start activity (including
4384         // permission grants) as any app that may launch one of your own activities.  So
4385         // we will only allow this to be done from activities that are part of the core framework,
4386         // and then only when they are running as the system.
4387         final ActivityRecord sourceRecord;
4388         final int targetUid;
4389         final String targetPackage;
4390         synchronized (this) {
4391             if (resultTo == null) {
4392                 throw new SecurityException("Must be called from an activity");
4393             }
4394             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395             if (sourceRecord == null) {
4396                 throw new SecurityException("Called with bad activity token: " + resultTo);
4397             }
4398             if (!sourceRecord.info.packageName.equals("android")) {
4399                 throw new SecurityException(
4400                         "Must be called from an activity that is declared in the android package");
4401             }
4402             if (sourceRecord.app == null) {
4403                 throw new SecurityException("Called without a process attached to activity");
4404             }
4405             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406                 // This is still okay, as long as this activity is running under the
4407                 // uid of the original calling activity.
4408                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409                     throw new SecurityException(
4410                             "Calling activity in uid " + sourceRecord.app.uid
4411                                     + " must be system uid or original calling uid "
4412                                     + sourceRecord.launchedFromUid);
4413                 }
4414             }
4415             if (ignoreTargetSecurity) {
4416                 if (intent.getComponent() == null) {
4417                     throw new SecurityException(
4418                             "Component must be specified with ignoreTargetSecurity");
4419                 }
4420                 if (intent.getSelector() != null) {
4421                     throw new SecurityException(
4422                             "Selector not allowed with ignoreTargetSecurity");
4423                 }
4424             }
4425             targetUid = sourceRecord.launchedFromUid;
4426             targetPackage = sourceRecord.launchedFromPackage;
4427         }
4428
4429         if (userId == UserHandle.USER_NULL) {
4430             userId = UserHandle.getUserId(sourceRecord.app.uid);
4431         }
4432
4433         // TODO: Switch to user app stacks here.
4434         try {
4435             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4438             return ret;
4439         } catch (SecurityException e) {
4440             // XXX need to figure out how to propagate to original app.
4441             // A SecurityException here is generally actually a fault of the original
4442             // calling activity (such as a fairly granting permissions), so propagate it
4443             // back to them.
4444             /*
4445             StringBuilder msg = new StringBuilder();
4446             msg.append("While launching");
4447             msg.append(intent.toString());
4448             msg.append(": ");
4449             msg.append(e.getMessage());
4450             */
4451             throw e;
4452         }
4453     }
4454
4455     @Override
4456     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459         enforceNotIsolatedCaller("startActivityAndWait");
4460         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462         WaitResult res = new WaitResult();
4463         // TODO: Switch to user app stacks here.
4464         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466                 bOptions, false, userId, null, null);
4467         return res;
4468     }
4469
4470     @Override
4471     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473             int startFlags, Configuration config, Bundle bOptions, int userId) {
4474         enforceNotIsolatedCaller("startActivityWithConfig");
4475         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477         // TODO: Switch to user app stacks here.
4478         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480                 null, null, config, bOptions, false, userId, null, null);
4481         return ret;
4482     }
4483
4484     @Override
4485     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488             throws TransactionTooLargeException {
4489         enforceNotIsolatedCaller("startActivityIntentSender");
4490         // Refuse possible leaked file descriptors
4491         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492             throw new IllegalArgumentException("File descriptors passed in Intent");
4493         }
4494
4495         IIntentSender sender = intent.getTarget();
4496         if (!(sender instanceof PendingIntentRecord)) {
4497             throw new IllegalArgumentException("Bad PendingIntent object");
4498         }
4499
4500         PendingIntentRecord pir = (PendingIntentRecord)sender;
4501
4502         synchronized (this) {
4503             // If this is coming from the currently resumed activity, it is
4504             // effectively saying that app switches are allowed at this point.
4505             final ActivityStack stack = getFocusedStack();
4506             if (stack.mResumedActivity != null &&
4507                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508                 mAppSwitchesAllowedTime = 0;
4509             }
4510         }
4511         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4513         return ret;
4514     }
4515
4516     @Override
4517     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518             Intent intent, String resolvedType, IVoiceInteractionSession session,
4519             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520             Bundle bOptions, int userId) {
4521         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522                 != PackageManager.PERMISSION_GRANTED) {
4523             String msg = "Permission Denial: startVoiceActivity() from pid="
4524                     + Binder.getCallingPid()
4525                     + ", uid=" + Binder.getCallingUid()
4526                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4527             Slog.w(TAG, msg);
4528             throw new SecurityException(msg);
4529         }
4530         if (session == null || interactor == null) {
4531             throw new NullPointerException("null session or interactor");
4532         }
4533         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535         // TODO: Switch to user app stacks here.
4536         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538                 null, bOptions, false, userId, null, null);
4539     }
4540
4541     @Override
4542     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543             throws RemoteException {
4544         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545         synchronized (this) {
4546             ActivityRecord activity = getFocusedStack().topActivity();
4547             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4549             }
4550             if (mRunningVoice != null || activity.task.voiceSession != null
4551                     || activity.voiceSession != null) {
4552                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4553                 return;
4554             }
4555             if (activity.pendingVoiceInteractionStart) {
4556                 Slog.w(TAG, "Pending start of voice interaction already.");
4557                 return;
4558             }
4559             activity.pendingVoiceInteractionStart = true;
4560         }
4561         LocalServices.getService(VoiceInteractionManagerInternal.class)
4562                 .startLocalVoiceInteraction(callingActivity, options);
4563     }
4564
4565     @Override
4566     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567         LocalServices.getService(VoiceInteractionManagerInternal.class)
4568                 .stopLocalVoiceInteraction(callingActivity);
4569     }
4570
4571     @Override
4572     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574                 .supportsLocalVoiceInteraction();
4575     }
4576
4577     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580         if (activityToCallback == null) return;
4581         activityToCallback.setVoiceSessionLocked(voiceSession);
4582
4583         // Inform the activity
4584         try {
4585             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4586                     voiceInteractor);
4587             long token = Binder.clearCallingIdentity();
4588             try {
4589                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4590             } finally {
4591                 Binder.restoreCallingIdentity(token);
4592             }
4593             // TODO: VI Should we cache the activity so that it's easier to find later
4594             // rather than scan through all the stacks and activities?
4595         } catch (RemoteException re) {
4596             activityToCallback.clearVoiceSessionLocked();
4597             // TODO: VI Should this terminate the voice session?
4598         }
4599     }
4600
4601     @Override
4602     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603         synchronized (this) {
4604             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4605                 if (keepAwake) {
4606                     mVoiceWakeLock.acquire();
4607                 } else {
4608                     mVoiceWakeLock.release();
4609                 }
4610             }
4611         }
4612     }
4613
4614     @Override
4615     public boolean startNextMatchingActivity(IBinder callingActivity,
4616             Intent intent, Bundle bOptions) {
4617         // Refuse possible leaked file descriptors
4618         if (intent != null && intent.hasFileDescriptors() == true) {
4619             throw new IllegalArgumentException("File descriptors passed in Intent");
4620         }
4621         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4622
4623         synchronized (this) {
4624             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4625             if (r == null) {
4626                 ActivityOptions.abort(options);
4627                 return false;
4628             }
4629             if (r.app == null || r.app.thread == null) {
4630                 // The caller is not running...  d'oh!
4631                 ActivityOptions.abort(options);
4632                 return false;
4633             }
4634             intent = new Intent(intent);
4635             // The caller is not allowed to change the data.
4636             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637             // And we are resetting to find the next component...
4638             intent.setComponent(null);
4639
4640             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4641
4642             ActivityInfo aInfo = null;
4643             try {
4644                 List<ResolveInfo> resolves =
4645                     AppGlobals.getPackageManager().queryIntentActivities(
4646                             intent, r.resolvedType,
4647                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648                             UserHandle.getCallingUserId()).getList();
4649
4650                 // Look for the original activity in the list...
4651                 final int N = resolves != null ? resolves.size() : 0;
4652                 for (int i=0; i<N; i++) {
4653                     ResolveInfo rInfo = resolves.get(i);
4654                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4655                             && rInfo.activityInfo.name.equals(r.info.name)) {
4656                         // We found the current one...  the next matching is
4657                         // after it.
4658                         i++;
4659                         if (i<N) {
4660                             aInfo = resolves.get(i).activityInfo;
4661                         }
4662                         if (debug) {
4663                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664                                     + "/" + r.info.name);
4665                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4667                         }
4668                         break;
4669                     }
4670                 }
4671             } catch (RemoteException e) {
4672             }
4673
4674             if (aInfo == null) {
4675                 // Nobody who is next!
4676                 ActivityOptions.abort(options);
4677                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4678                 return false;
4679             }
4680
4681             intent.setComponent(new ComponentName(
4682                     aInfo.applicationInfo.packageName, aInfo.name));
4683             intent.setFlags(intent.getFlags()&~(
4684                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687                     Intent.FLAG_ACTIVITY_NEW_TASK));
4688
4689             // Okay now we need to start the new activity, replacing the
4690             // currently running activity.  This is a little tricky because
4691             // we want to start the new one as if the current one is finished,
4692             // but not finish the current one first so that there is no flicker.
4693             // And thus...
4694             final boolean wasFinishing = r.finishing;
4695             r.finishing = true;
4696
4697             // Propagate reply information over to the new activity.
4698             final ActivityRecord resultTo = r.resultTo;
4699             final String resultWho = r.resultWho;
4700             final int requestCode = r.requestCode;
4701             r.resultTo = null;
4702             if (resultTo != null) {
4703                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4704             }
4705
4706             final long origId = Binder.clearCallingIdentity();
4707             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711                     false, false, null, null, null);
4712             Binder.restoreCallingIdentity(origId);
4713
4714             r.finishing = wasFinishing;
4715             if (res != ActivityManager.START_SUCCESS) {
4716                 return false;
4717             }
4718             return true;
4719         }
4720     }
4721
4722     @Override
4723     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725             String msg = "Permission Denial: startActivityFromRecents called without " +
4726                     START_TASKS_FROM_RECENTS;
4727             Slog.w(TAG, msg);
4728             throw new SecurityException(msg);
4729         }
4730         final long origId = Binder.clearCallingIdentity();
4731         try {
4732             synchronized (this) {
4733                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4734             }
4735         } finally {
4736             Binder.restoreCallingIdentity(origId);
4737         }
4738     }
4739
4740     final int startActivityInPackage(int uid, String callingPackage,
4741             Intent intent, String resolvedType, IBinder resultTo,
4742             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743             IActivityContainer container, TaskRecord inTask) {
4744
4745         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4747
4748         // TODO: Switch to user app stacks here.
4749         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4750                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751                 null, null, null, bOptions, false, userId, container, inTask);
4752         return ret;
4753     }
4754
4755     @Override
4756     public final int startActivities(IApplicationThread caller, String callingPackage,
4757             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4758             int userId) {
4759         enforceNotIsolatedCaller("startActivities");
4760         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762         // TODO: Switch to user app stacks here.
4763         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764                 resolvedTypes, resultTo, bOptions, userId);
4765         return ret;
4766     }
4767
4768     final int startActivitiesInPackage(int uid, String callingPackage,
4769             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770             Bundle bOptions, int userId) {
4771
4772         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774         // TODO: Switch to user app stacks here.
4775         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776                 resultTo, bOptions, userId);
4777         return ret;
4778     }
4779
4780     @Override
4781     public void reportActivityFullyDrawn(IBinder token) {
4782         synchronized (this) {
4783             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4784             if (r == null) {
4785                 return;
4786             }
4787             r.reportFullyDrawnLocked();
4788         }
4789     }
4790
4791     @Override
4792     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793         synchronized (this) {
4794             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4795             if (r == null) {
4796                 return;
4797             }
4798             TaskRecord task = r.task;
4799             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800                 // Fixed screen orientation isn't supported when activities aren't in full screen
4801                 // mode.
4802                 return;
4803             }
4804             final long origId = Binder.clearCallingIdentity();
4805             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808             if (config != null) {
4809                 r.frozenBeforeDestroy = true;
4810                 if (!updateConfigurationLocked(config, r, false)) {
4811                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4812                 }
4813             }
4814             Binder.restoreCallingIdentity(origId);
4815         }
4816     }
4817
4818     @Override
4819     public int getRequestedOrientation(IBinder token) {
4820         synchronized (this) {
4821             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822             if (r == null) {
4823                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4824             }
4825             return mWindowManager.getAppOrientation(r.appToken);
4826         }
4827     }
4828
4829     /**
4830      * This is the internal entry point for handling Activity.finish().
4831      *
4832      * @param token The Binder token referencing the Activity we want to finish.
4833      * @param resultCode Result code, if any, from this Activity.
4834      * @param resultData Result data (Intent), if any, from this Activity.
4835      * @param finishTask Whether to finish the task associated with this Activity.
4836      *
4837      * @return Returns true if the activity successfully finished, or false if it is still running.
4838      */
4839     @Override
4840     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4841             int finishTask) {
4842         // Refuse possible leaked file descriptors
4843         if (resultData != null && resultData.hasFileDescriptors() == true) {
4844             throw new IllegalArgumentException("File descriptors passed in Intent");
4845         }
4846
4847         synchronized(this) {
4848             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4849             if (r == null) {
4850                 return true;
4851             }
4852             // Keep track of the root activity of the task before we finish it
4853             TaskRecord tr = r.task;
4854             ActivityRecord rootR = tr.getRootActivity();
4855             if (rootR == null) {
4856                 Slog.w(TAG, "Finishing task with all activities already finished");
4857             }
4858             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4859             // finish.
4860             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861                     mStackSupervisor.isLastLockedTask(tr)) {
4862                 Slog.i(TAG, "Not finishing task in lock task mode");
4863                 mStackSupervisor.showLockTaskToast();
4864                 return false;
4865             }
4866             if (mController != null) {
4867                 // Find the first activity that is not finishing.
4868                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4869                 if (next != null) {
4870                     // ask watcher if this is allowed
4871                     boolean resumeOK = true;
4872                     try {
4873                         resumeOK = mController.activityResuming(next.packageName);
4874                     } catch (RemoteException e) {
4875                         mController = null;
4876                         Watchdog.getInstance().setActivityController(null);
4877                     }
4878
4879                     if (!resumeOK) {
4880                         Slog.i(TAG, "Not finishing activity because controller resumed");
4881                         return false;
4882                     }
4883                 }
4884             }
4885             final long origId = Binder.clearCallingIdentity();
4886             try {
4887                 boolean res;
4888                 final boolean finishWithRootActivity =
4889                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891                         || (finishWithRootActivity && r == rootR)) {
4892                     // If requested, remove the task that is associated to this activity only if it
4893                     // was the root activity in the task. The result code and data is ignored
4894                     // because we don't support returning them across task boundaries. Also, to
4895                     // keep backwards compatibility we remove the task from recents when finishing
4896                     // task with root activity.
4897                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4898                     if (!res) {
4899                         Slog.i(TAG, "Removing task failed to finish activity");
4900                     }
4901                 } else {
4902                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903                             resultData, "app-request", true);
4904                     if (!res) {
4905                         Slog.i(TAG, "Failed to finish by app-request");
4906                     }
4907                 }
4908                 return res;
4909             } finally {
4910                 Binder.restoreCallingIdentity(origId);
4911             }
4912         }
4913     }
4914
4915     @Override
4916     public final void finishHeavyWeightApp() {
4917         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918                 != PackageManager.PERMISSION_GRANTED) {
4919             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920                     + Binder.getCallingPid()
4921                     + ", uid=" + Binder.getCallingUid()
4922                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4923             Slog.w(TAG, msg);
4924             throw new SecurityException(msg);
4925         }
4926
4927         synchronized(this) {
4928             if (mHeavyWeightProcess == null) {
4929                 return;
4930             }
4931
4932             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933             for (int i = 0; i < activities.size(); i++) {
4934                 ActivityRecord r = activities.get(i);
4935                 if (!r.finishing && r.isInStackLocked()) {
4936                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937                             null, "finish-heavy", true);
4938                 }
4939             }
4940
4941             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942                     mHeavyWeightProcess.userId, 0));
4943             mHeavyWeightProcess = null;
4944         }
4945     }
4946
4947     @Override
4948     public void crashApplication(int uid, int initialPid, String packageName,
4949             String message) {
4950         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951                 != PackageManager.PERMISSION_GRANTED) {
4952             String msg = "Permission Denial: crashApplication() from pid="
4953                     + Binder.getCallingPid()
4954                     + ", uid=" + Binder.getCallingUid()
4955                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4956             Slog.w(TAG, msg);
4957             throw new SecurityException(msg);
4958         }
4959
4960         synchronized(this) {
4961             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4962         }
4963     }
4964
4965     @Override
4966     public final void finishSubActivity(IBinder token, String resultWho,
4967             int requestCode) {
4968         synchronized(this) {
4969             final long origId = Binder.clearCallingIdentity();
4970             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4971             if (r != null) {
4972                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4973             }
4974             Binder.restoreCallingIdentity(origId);
4975         }
4976     }
4977
4978     @Override
4979     public boolean finishActivityAffinity(IBinder token) {
4980         synchronized(this) {
4981             final long origId = Binder.clearCallingIdentity();
4982             try {
4983                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984                 if (r == null) {
4985                     return false;
4986                 }
4987
4988                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4989                 // can finish.
4990                 final TaskRecord task = r.task;
4991                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993                     mStackSupervisor.showLockTaskToast();
4994                     return false;
4995                 }
4996                 return task.stack.finishActivityAffinityLocked(r);
4997             } finally {
4998                 Binder.restoreCallingIdentity(origId);
4999             }
5000         }
5001     }
5002
5003     @Override
5004     public void finishVoiceTask(IVoiceInteractionSession session) {
5005         synchronized (this) {
5006             final long origId = Binder.clearCallingIdentity();
5007             try {
5008                 // TODO: VI Consider treating local voice interactions and voice tasks
5009                 // differently here
5010                 mStackSupervisor.finishVoiceTask(session);
5011             } finally {
5012                 Binder.restoreCallingIdentity(origId);
5013             }
5014         }
5015
5016     }
5017
5018     @Override
5019     public boolean releaseActivityInstance(IBinder token) {
5020         synchronized(this) {
5021             final long origId = Binder.clearCallingIdentity();
5022             try {
5023                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5024                 if (r == null) {
5025                     return false;
5026                 }
5027                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5028             } finally {
5029                 Binder.restoreCallingIdentity(origId);
5030             }
5031         }
5032     }
5033
5034     @Override
5035     public void releaseSomeActivities(IApplicationThread appInt) {
5036         synchronized(this) {
5037             final long origId = Binder.clearCallingIdentity();
5038             try {
5039                 ProcessRecord app = getRecordForAppLocked(appInt);
5040                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5041             } finally {
5042                 Binder.restoreCallingIdentity(origId);
5043             }
5044         }
5045     }
5046
5047     @Override
5048     public boolean willActivityBeVisible(IBinder token) {
5049         synchronized(this) {
5050             ActivityStack stack = ActivityRecord.getStackLocked(token);
5051             if (stack != null) {
5052                 return stack.willActivityBeVisibleLocked(token);
5053             }
5054             return false;
5055         }
5056     }
5057
5058     @Override
5059     public void overridePendingTransition(IBinder token, String packageName,
5060             int enterAnim, int exitAnim) {
5061         synchronized(this) {
5062             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5063             if (self == null) {
5064                 return;
5065             }
5066
5067             final long origId = Binder.clearCallingIdentity();
5068
5069             if (self.state == ActivityState.RESUMED
5070                     || self.state == ActivityState.PAUSING) {
5071                 mWindowManager.overridePendingAppTransition(packageName,
5072                         enterAnim, exitAnim, null);
5073             }
5074
5075             Binder.restoreCallingIdentity(origId);
5076         }
5077     }
5078
5079     /**
5080      * Main function for removing an existing process from the activity manager
5081      * as a result of that process going away.  Clears out all connections
5082      * to the process.
5083      */
5084     private final void handleAppDiedLocked(ProcessRecord app,
5085             boolean restarting, boolean allowRestart) {
5086         int pid = app.pid;
5087         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088                 false /*replacingPid*/);
5089         if (!kept && !restarting) {
5090             removeLruProcessLocked(app);
5091             if (pid > 0) {
5092                 ProcessList.remove(pid);
5093             }
5094         }
5095
5096         if (mProfileProc == app) {
5097             clearProfilerLocked();
5098         }
5099
5100         // Remove this application's activities from active lists.
5101         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5102
5103         app.activities.clear();
5104
5105         if (app.instrumentationClass != null) {
5106             Slog.w(TAG, "Crash of app " + app.processName
5107                   + " running instrumentation " + app.instrumentationClass);
5108             Bundle info = new Bundle();
5109             info.putString("shortMsg", "Process crashed.");
5110             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5111         }
5112
5113         if (!restarting && hasVisibleActivities
5114                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115             // If there was nothing to resume, and we are not already restarting this process, but
5116             // there is a visible activity that is hosted by the process...  then make sure all
5117             // visible activities are running, taking care of restarting this process.
5118             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5119         }
5120     }
5121
5122     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123         IBinder threadBinder = thread.asBinder();
5124         // Find the application record.
5125         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126             ProcessRecord rec = mLruProcesses.get(i);
5127             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5128                 return i;
5129             }
5130         }
5131         return -1;
5132     }
5133
5134     final ProcessRecord getRecordForAppLocked(
5135             IApplicationThread thread) {
5136         if (thread == null) {
5137             return null;
5138         }
5139
5140         int appIndex = getLRURecordIndexForAppLocked(thread);
5141         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5142     }
5143
5144     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145         // If there are no longer any background processes running,
5146         // and the app that died was not running instrumentation,
5147         // then tell everyone we are now low on memory.
5148         boolean haveBg = false;
5149         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150             ProcessRecord rec = mLruProcesses.get(i);
5151             if (rec.thread != null
5152                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5153                 haveBg = true;
5154                 break;
5155             }
5156         }
5157
5158         if (!haveBg) {
5159             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5160             if (doReport) {
5161                 long now = SystemClock.uptimeMillis();
5162                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5163                     doReport = false;
5164                 } else {
5165                     mLastMemUsageReportTime = now;
5166                 }
5167             }
5168             final ArrayList<ProcessMemInfo> memInfos
5169                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171             long now = SystemClock.uptimeMillis();
5172             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173                 ProcessRecord rec = mLruProcesses.get(i);
5174                 if (rec == dyingProc || rec.thread == null) {
5175                     continue;
5176                 }
5177                 if (doReport) {
5178                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5180                 }
5181                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182                     // The low memory report is overriding any current
5183                     // state for a GC request.  Make sure to do
5184                     // heavy/important/visible/foreground processes first.
5185                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186                         rec.lastRequestedGc = 0;
5187                     } else {
5188                         rec.lastRequestedGc = rec.lastLowMemory;
5189                     }
5190                     rec.reportLowMemory = true;
5191                     rec.lastLowMemory = now;
5192                     mProcessesToGc.remove(rec);
5193                     addProcessToGcListLocked(rec);
5194                 }
5195             }
5196             if (doReport) {
5197                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198                 mHandler.sendMessage(msg);
5199             }
5200             scheduleAppGcsLocked();
5201         }
5202     }
5203
5204     final void appDiedLocked(ProcessRecord app) {
5205        appDiedLocked(app, app.pid, app.thread, false);
5206     }
5207
5208     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209             boolean fromBinderDied) {
5210         // First check if this ProcessRecord is actually active for the pid.
5211         synchronized (mPidsSelfLocked) {
5212             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213             if (curProc != app) {
5214                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5215                 return;
5216             }
5217         }
5218
5219         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220         synchronized (stats) {
5221             stats.noteProcessDiedLocked(app.info.uid, pid);
5222         }
5223
5224         if (!app.killed) {
5225             if (!fromBinderDied) {
5226                 Process.killProcessQuiet(pid);
5227             }
5228             killProcessGroup(app.uid, pid);
5229             app.killed = true;
5230         }
5231
5232         // Clean up already done if the process has been re-started.
5233         if (app.pid == pid && app.thread != null &&
5234                 app.thread.asBinder() == thread.asBinder()) {
5235             boolean doLowMem = app.instrumentationClass == null;
5236             boolean doOomAdj = doLowMem;
5237             if (!app.killedByAm) {
5238                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5239                         + ") has died");
5240                 mAllowLowerMemLevel = true;
5241             } else {
5242                 // Note that we always want to do oom adj to update our state with the
5243                 // new number of procs.
5244                 mAllowLowerMemLevel = false;
5245                 doLowMem = false;
5246             }
5247             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250             handleAppDiedLocked(app, false, true);
5251
5252             if (doOomAdj) {
5253                 updateOomAdjLocked();
5254             }
5255             if (doLowMem) {
5256                 doLowMemReportIfNeededLocked(app);
5257             }
5258         } else if (app.pid != pid) {
5259             // A new process has already been started.
5260             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261                     + ") has died and restarted (pid " + app.pid + ").");
5262             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263         } else if (DEBUG_PROCESSES) {
5264             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265                     + thread.asBinder());
5266         }
5267     }
5268
5269     /**
5270      * If a stack trace dump file is configured, dump process stack traces.
5271      * @param clearTraces causes the dump file to be erased prior to the new
5272      *    traces being written, if true; when false, the new traces will be
5273      *    appended to any existing file content.
5274      * @param firstPids of dalvik VM processes to dump stack traces for first
5275      * @param lastPids of dalvik VM processes to dump stack traces for last
5276      * @param nativeProcs optional list of native process names to dump stack crawls
5277      * @return file containing stack traces, or null if no dump file is configured
5278      */
5279     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282         if (tracesPath == null || tracesPath.length() == 0) {
5283             return null;
5284         }
5285
5286         File tracesFile = new File(tracesPath);
5287         try {
5288             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289             tracesFile.createNewFile();
5290             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291         } catch (IOException e) {
5292             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5293             return null;
5294         }
5295
5296         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5297         return tracesFile;
5298     }
5299
5300     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302         // Use a FileObserver to detect when traces finish writing.
5303         // The order of traces is considered important to maintain for legibility.
5304         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5305             @Override
5306             public synchronized void onEvent(int event, String path) { notify(); }
5307         };
5308
5309         try {
5310             observer.startWatching();
5311
5312             // First collect all of the stacks of the most important pids.
5313             if (firstPids != null) {
5314                 try {
5315                     int num = firstPids.size();
5316                     for (int i = 0; i < num; i++) {
5317                         synchronized (observer) {
5318                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319                                     + firstPids.get(i));
5320                             final long sime = SystemClock.elapsedRealtime();
5321                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5323                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5325                         }
5326                     }
5327                 } catch (InterruptedException e) {
5328                     Slog.wtf(TAG, e);
5329                 }
5330             }
5331
5332             // Next collect the stacks of the native pids
5333             if (nativeProcs != null) {
5334                 int[] pids = Process.getPidsForCommands(nativeProcs);
5335                 if (pids != null) {
5336                     for (int pid : pids) {
5337                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338                         final long sime = SystemClock.elapsedRealtime();
5339                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5342                     }
5343                 }
5344             }
5345
5346             // Lastly, measure CPU usage.
5347             if (processCpuTracker != null) {
5348                 processCpuTracker.init();
5349                 System.gc();
5350                 processCpuTracker.update();
5351                 try {
5352                     synchronized (processCpuTracker) {
5353                         processCpuTracker.wait(500); // measure over 1/2 second.
5354                     }
5355                 } catch (InterruptedException e) {
5356                 }
5357                 processCpuTracker.update();
5358
5359                 // We'll take the stack crawls of just the top apps using CPU.
5360                 final int N = processCpuTracker.countWorkingStats();
5361                 int numProcs = 0;
5362                 for (int i=0; i<N && numProcs<5; i++) {
5363                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5365                         numProcs++;
5366                         try {
5367                             synchronized (observer) {
5368                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5369                                         + stats.pid);
5370                                 final long stime = SystemClock.elapsedRealtime();
5371                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5373                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5375                             }
5376                         } catch (InterruptedException e) {
5377                             Slog.wtf(TAG, e);
5378                         }
5379                     } else if (DEBUG_ANR) {
5380                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5381                                 + stats.pid);
5382                     }
5383                 }
5384             }
5385         } finally {
5386             observer.stopWatching();
5387         }
5388     }
5389
5390     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391         if (true || IS_USER_BUILD) {
5392             return;
5393         }
5394         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395         if (tracesPath == null || tracesPath.length() == 0) {
5396             return;
5397         }
5398
5399         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400         StrictMode.allowThreadDiskWrites();
5401         try {
5402             final File tracesFile = new File(tracesPath);
5403             final File tracesDir = tracesFile.getParentFile();
5404             final File tracesTmp = new File(tracesDir, "__tmp__");
5405             try {
5406                 if (tracesFile.exists()) {
5407                     tracesTmp.delete();
5408                     tracesFile.renameTo(tracesTmp);
5409                 }
5410                 StringBuilder sb = new StringBuilder();
5411                 Time tobj = new Time();
5412                 tobj.set(System.currentTimeMillis());
5413                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5414                 sb.append(": ");
5415                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416                 sb.append(" since ");
5417                 sb.append(msg);
5418                 FileOutputStream fos = new FileOutputStream(tracesFile);
5419                 fos.write(sb.toString().getBytes());
5420                 if (app == null) {
5421                     fos.write("\n*** No application process!".getBytes());
5422                 }
5423                 fos.close();
5424                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425             } catch (IOException e) {
5426                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5427                 return;
5428             }
5429
5430             if (app != null) {
5431                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432                 firstPids.add(app.pid);
5433                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5434             }
5435
5436             File lastTracesFile = null;
5437             File curTracesFile = null;
5438             for (int i=9; i>=0; i--) {
5439                 String name = String.format(Locale.US, "slow%02d.txt", i);
5440                 curTracesFile = new File(tracesDir, name);
5441                 if (curTracesFile.exists()) {
5442                     if (lastTracesFile != null) {
5443                         curTracesFile.renameTo(lastTracesFile);
5444                     } else {
5445                         curTracesFile.delete();
5446                     }
5447                 }
5448                 lastTracesFile = curTracesFile;
5449             }
5450             tracesFile.renameTo(curTracesFile);
5451             if (tracesTmp.exists()) {
5452                 tracesTmp.renameTo(tracesFile);
5453             }
5454         } finally {
5455             StrictMode.setThreadPolicy(oldPolicy);
5456         }
5457     }
5458
5459     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460         if (!mLaunchWarningShown) {
5461             mLaunchWarningShown = true;
5462             mUiHandler.post(new Runnable() {
5463                 @Override
5464                 public void run() {
5465                     synchronized (ActivityManagerService.this) {
5466                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5467                         d.show();
5468                         mUiHandler.postDelayed(new Runnable() {
5469                             @Override
5470                             public void run() {
5471                                 synchronized (ActivityManagerService.this) {
5472                                     d.dismiss();
5473                                     mLaunchWarningShown = false;
5474                                 }
5475                             }
5476                         }, 4000);
5477                     }
5478                 }
5479             });
5480         }
5481     }
5482
5483     @Override
5484     public boolean clearApplicationUserData(final String packageName,
5485             final IPackageDataObserver observer, int userId) {
5486         enforceNotIsolatedCaller("clearApplicationUserData");
5487         int uid = Binder.getCallingUid();
5488         int pid = Binder.getCallingPid();
5489         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5491
5492
5493         long callingId = Binder.clearCallingIdentity();
5494         try {
5495             IPackageManager pm = AppGlobals.getPackageManager();
5496             int pkgUid = -1;
5497             synchronized(this) {
5498                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499                         userId, packageName)) {
5500                     throw new SecurityException(
5501                             "Cannot clear data for a protected package: " + packageName);
5502                 }
5503
5504                 try {
5505                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506                 } catch (RemoteException e) {
5507                 }
5508                 if (pkgUid == -1) {
5509                     Slog.w(TAG, "Invalid packageName: " + packageName);
5510                     if (observer != null) {
5511                         try {
5512                             observer.onRemoveCompleted(packageName, false);
5513                         } catch (RemoteException e) {
5514                             Slog.i(TAG, "Observer no longer exists.");
5515                         }
5516                     }
5517                     return false;
5518                 }
5519                 if (uid == pkgUid || checkComponentPermission(
5520                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5521                         pid, uid, -1, true)
5522                         == PackageManager.PERMISSION_GRANTED) {
5523                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5524                 } else {
5525                     throw new SecurityException("PID " + pid + " does not have permission "
5526                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527                                     + " of package " + packageName);
5528                 }
5529
5530                 // Remove all tasks match the cleared application package and user
5531                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532                     final TaskRecord tr = mRecentTasks.get(i);
5533                     final String taskPackageName =
5534                             tr.getBaseIntent().getComponent().getPackageName();
5535                     if (tr.userId != userId) continue;
5536                     if (!taskPackageName.equals(packageName)) continue;
5537                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5538                 }
5539             }
5540
5541             final int pkgUidF = pkgUid;
5542             final int userIdF = userId;
5543             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5544                 @Override
5545                 public void onRemoveCompleted(String packageName, boolean succeeded)
5546                         throws RemoteException {
5547                     synchronized (ActivityManagerService.this) {
5548                         finishForceStopPackageLocked(packageName, pkgUidF);
5549                     }
5550
5551                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552                             Uri.fromParts("package", packageName, null));
5553                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556                             null, null, 0, null, null, null, null, false, false, userIdF);
5557
5558                     if (observer != null) {
5559                         observer.onRemoveCompleted(packageName, succeeded);
5560                     }
5561                 }
5562             };
5563
5564             try {
5565                 // Clear application user data
5566                 pm.clearApplicationUserData(packageName, localObserver, userId);
5567
5568                 synchronized(this) {
5569                     // Remove all permissions granted from/to this package
5570                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5571                 }
5572
5573                 // Remove all zen rules created by this package; revoke it's zen access.
5574                 INotificationManager inm = NotificationManager.getService();
5575                 inm.removeAutomaticZenRules(packageName);
5576                 inm.setNotificationPolicyAccessGranted(packageName, false);
5577
5578             } catch (RemoteException e) {
5579             }
5580         } finally {
5581             Binder.restoreCallingIdentity(callingId);
5582         }
5583         return true;
5584     }
5585
5586     @Override
5587     public void killBackgroundProcesses(final String packageName, int userId) {
5588         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589                 != PackageManager.PERMISSION_GRANTED &&
5590                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591                         != PackageManager.PERMISSION_GRANTED) {
5592             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593                     + Binder.getCallingPid()
5594                     + ", uid=" + Binder.getCallingUid()
5595                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5596             Slog.w(TAG, msg);
5597             throw new SecurityException(msg);
5598         }
5599
5600         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602         long callingId = Binder.clearCallingIdentity();
5603         try {
5604             IPackageManager pm = AppGlobals.getPackageManager();
5605             synchronized(this) {
5606                 int appId = -1;
5607                 try {
5608                     appId = UserHandle.getAppId(
5609                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610                 } catch (RemoteException e) {
5611                 }
5612                 if (appId == -1) {
5613                     Slog.w(TAG, "Invalid packageName: " + packageName);
5614                     return;
5615                 }
5616                 killPackageProcessesLocked(packageName, appId, userId,
5617                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5618             }
5619         } finally {
5620             Binder.restoreCallingIdentity(callingId);
5621         }
5622     }
5623
5624     @Override
5625     public void killAllBackgroundProcesses() {
5626         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627                 != PackageManager.PERMISSION_GRANTED) {
5628             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5631             Slog.w(TAG, msg);
5632             throw new SecurityException(msg);
5633         }
5634
5635         final long callingId = Binder.clearCallingIdentity();
5636         try {
5637             synchronized (this) {
5638                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639                 final int NP = mProcessNames.getMap().size();
5640                 for (int ip = 0; ip < NP; ip++) {
5641                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642                     final int NA = apps.size();
5643                     for (int ia = 0; ia < NA; ia++) {
5644                         final ProcessRecord app = apps.valueAt(ia);
5645                         if (app.persistent) {
5646                             // We don't kill persistent processes.
5647                             continue;
5648                         }
5649                         if (app.removed) {
5650                             procs.add(app);
5651                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5652                             app.removed = true;
5653                             procs.add(app);
5654                         }
5655                     }
5656                 }
5657
5658                 final int N = procs.size();
5659                 for (int i = 0; i < N; i++) {
5660                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5661                 }
5662
5663                 mAllowLowerMemLevel = true;
5664
5665                 updateOomAdjLocked();
5666                 doLowMemReportIfNeededLocked(null);
5667             }
5668         } finally {
5669             Binder.restoreCallingIdentity(callingId);
5670         }
5671     }
5672
5673     /**
5674      * Kills all background processes, except those matching any of the
5675      * specified properties.
5676      *
5677      * @param minTargetSdk the target SDK version at or above which to preserve
5678      *                     processes, or {@code -1} to ignore the target SDK
5679      * @param maxProcState the process state at or below which to preserve
5680      *                     processes, or {@code -1} to ignore the process state
5681      */
5682     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684                 != PackageManager.PERMISSION_GRANTED) {
5685             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5688             Slog.w(TAG, msg);
5689             throw new SecurityException(msg);
5690         }
5691
5692         final long callingId = Binder.clearCallingIdentity();
5693         try {
5694             synchronized (this) {
5695                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696                 final int NP = mProcessNames.getMap().size();
5697                 for (int ip = 0; ip < NP; ip++) {
5698                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699                     final int NA = apps.size();
5700                     for (int ia = 0; ia < NA; ia++) {
5701                         final ProcessRecord app = apps.valueAt(ia);
5702                         if (app.removed) {
5703                             procs.add(app);
5704                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5706                             app.removed = true;
5707                             procs.add(app);
5708                         }
5709                     }
5710                 }
5711
5712                 final int N = procs.size();
5713                 for (int i = 0; i < N; i++) {
5714                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5715                 }
5716             }
5717         } finally {
5718             Binder.restoreCallingIdentity(callingId);
5719         }
5720     }
5721
5722     @Override
5723     public void forceStopPackage(final String packageName, int userId) {
5724         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725                 != PackageManager.PERMISSION_GRANTED) {
5726             String msg = "Permission Denial: forceStopPackage() from pid="
5727                     + Binder.getCallingPid()
5728                     + ", uid=" + Binder.getCallingUid()
5729                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5730             Slog.w(TAG, msg);
5731             throw new SecurityException(msg);
5732         }
5733         final int callingPid = Binder.getCallingPid();
5734         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736         long callingId = Binder.clearCallingIdentity();
5737         try {
5738             IPackageManager pm = AppGlobals.getPackageManager();
5739             synchronized(this) {
5740                 int[] users = userId == UserHandle.USER_ALL
5741                         ? mUserController.getUsers() : new int[] { userId };
5742                 for (int user : users) {
5743                     int pkgUid = -1;
5744                     try {
5745                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5746                                 user);
5747                     } catch (RemoteException e) {
5748                     }
5749                     if (pkgUid == -1) {
5750                         Slog.w(TAG, "Invalid packageName: " + packageName);
5751                         continue;
5752                     }
5753                     try {
5754                         pm.setPackageStoppedState(packageName, true, user);
5755                     } catch (RemoteException e) {
5756                     } catch (IllegalArgumentException e) {
5757                         Slog.w(TAG, "Failed trying to unstop package "
5758                                 + packageName + ": " + e);
5759                     }
5760                     if (mUserController.isUserRunningLocked(user, 0)) {
5761                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762                         finishForceStopPackageLocked(packageName, pkgUid);
5763                     }
5764                 }
5765             }
5766         } finally {
5767             Binder.restoreCallingIdentity(callingId);
5768         }
5769     }
5770
5771     @Override
5772     public void addPackageDependency(String packageName) {
5773         synchronized (this) {
5774             int callingPid = Binder.getCallingPid();
5775             if (callingPid == Process.myPid()) {
5776                 //  Yeah, um, no.
5777                 return;
5778             }
5779             ProcessRecord proc;
5780             synchronized (mPidsSelfLocked) {
5781                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5782             }
5783             if (proc != null) {
5784                 if (proc.pkgDeps == null) {
5785                     proc.pkgDeps = new ArraySet<String>(1);
5786                 }
5787                 proc.pkgDeps.add(packageName);
5788             }
5789         }
5790     }
5791
5792     /*
5793      * The pkg name and app id have to be specified.
5794      */
5795     @Override
5796     public void killApplication(String pkg, int appId, int userId, String reason) {
5797         if (pkg == null) {
5798             return;
5799         }
5800         // Make sure the uid is valid.
5801         if (appId < 0) {
5802             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5803             return;
5804         }
5805         int callerUid = Binder.getCallingUid();
5806         // Only the system server can kill an application
5807         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808             // Post an aysnc message to kill the application
5809             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5810             msg.arg1 = appId;
5811             msg.arg2 = userId;
5812             Bundle bundle = new Bundle();
5813             bundle.putString("pkg", pkg);
5814             bundle.putString("reason", reason);
5815             msg.obj = bundle;
5816             mHandler.sendMessage(msg);
5817         } else {
5818             throw new SecurityException(callerUid + " cannot kill pkg: " +
5819                     pkg);
5820         }
5821     }
5822
5823     @Override
5824     public void closeSystemDialogs(String reason) {
5825         enforceNotIsolatedCaller("closeSystemDialogs");
5826
5827         final int pid = Binder.getCallingPid();
5828         final int uid = Binder.getCallingUid();
5829         final long origId = Binder.clearCallingIdentity();
5830         try {
5831             synchronized (this) {
5832                 // Only allow this from foreground processes, so that background
5833                 // applications can't abuse it to prevent system UI from being shown.
5834                 if (uid >= Process.FIRST_APPLICATION_UID) {
5835                     ProcessRecord proc;
5836                     synchronized (mPidsSelfLocked) {
5837                         proc = mPidsSelfLocked.get(pid);
5838                     }
5839                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841                                 + " from background process " + proc);
5842                         return;
5843                     }
5844                 }
5845                 closeSystemDialogsLocked(reason);
5846             }
5847         } finally {
5848             Binder.restoreCallingIdentity(origId);
5849         }
5850     }
5851
5852     void closeSystemDialogsLocked(String reason) {
5853         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855                 | Intent.FLAG_RECEIVER_FOREGROUND);
5856         if (reason != null) {
5857             intent.putExtra("reason", reason);
5858         }
5859         mWindowManager.closeSystemDialogs(reason);
5860
5861         mStackSupervisor.closeSystemDialogsLocked();
5862
5863         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864                 AppOpsManager.OP_NONE, null, false, false,
5865                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5866     }
5867
5868     @Override
5869     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870         enforceNotIsolatedCaller("getProcessMemoryInfo");
5871         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872         for (int i=pids.length-1; i>=0; i--) {
5873             ProcessRecord proc;
5874             int oomAdj;
5875             synchronized (this) {
5876                 synchronized (mPidsSelfLocked) {
5877                     proc = mPidsSelfLocked.get(pids[i]);
5878                     oomAdj = proc != null ? proc.setAdj : 0;
5879                 }
5880             }
5881             infos[i] = new Debug.MemoryInfo();
5882             Debug.getMemoryInfo(pids[i], infos[i]);
5883             if (proc != null) {
5884                 synchronized (this) {
5885                     if (proc.thread != null && proc.setAdj == oomAdj) {
5886                         // Record this for posterity if the process has been stable.
5887                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888                                 infos[i].getTotalUss(), false, proc.pkgList);
5889                     }
5890                 }
5891             }
5892         }
5893         return infos;
5894     }
5895
5896     @Override
5897     public long[] getProcessPss(int[] pids) {
5898         enforceNotIsolatedCaller("getProcessPss");
5899         long[] pss = new long[pids.length];
5900         for (int i=pids.length-1; i>=0; i--) {
5901             ProcessRecord proc;
5902             int oomAdj;
5903             synchronized (this) {
5904                 synchronized (mPidsSelfLocked) {
5905                     proc = mPidsSelfLocked.get(pids[i]);
5906                     oomAdj = proc != null ? proc.setAdj : 0;
5907                 }
5908             }
5909             long[] tmpUss = new long[1];
5910             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5911             if (proc != null) {
5912                 synchronized (this) {
5913                     if (proc.thread != null && proc.setAdj == oomAdj) {
5914                         // Record this for posterity if the process has been stable.
5915                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5916                     }
5917                 }
5918             }
5919         }
5920         return pss;
5921     }
5922
5923     @Override
5924     public void killApplicationProcess(String processName, int uid) {
5925         if (processName == null) {
5926             return;
5927         }
5928
5929         int callerUid = Binder.getCallingUid();
5930         // Only the system server can kill an application
5931         if (callerUid == Process.SYSTEM_UID) {
5932             synchronized (this) {
5933                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934                 if (app != null && app.thread != null) {
5935                     try {
5936                         app.thread.scheduleSuicide();
5937                     } catch (RemoteException e) {
5938                         // If the other end already died, then our work here is done.
5939                     }
5940                 } else {
5941                     Slog.w(TAG, "Process/uid not found attempting kill of "
5942                             + processName + " / " + uid);
5943                 }
5944             }
5945         } else {
5946             throw new SecurityException(callerUid + " cannot kill app process: " +
5947                     processName);
5948         }
5949     }
5950
5951     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953                 false, true, false, false, UserHandle.getUserId(uid), reason);
5954     }
5955
5956     private void finishForceStopPackageLocked(final String packageName, int uid) {
5957         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958                 Uri.fromParts("package", packageName, null));
5959         if (!mProcessesReady) {
5960             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961                     | Intent.FLAG_RECEIVER_FOREGROUND);
5962         }
5963         intent.putExtra(Intent.EXTRA_UID, uid);
5964         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965         broadcastIntentLocked(null, null, intent,
5966                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5968     }
5969
5970
5971     private final boolean killPackageProcessesLocked(String packageName, int appId,
5972             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973             boolean doit, boolean evenPersistent, String reason) {
5974         ArrayList<ProcessRecord> procs = new ArrayList<>();
5975
5976         // Remove all processes this package may have touched: all with the
5977         // same UID (except for the system or root user), and all whose name
5978         // matches the package name.
5979         final int NP = mProcessNames.getMap().size();
5980         for (int ip=0; ip<NP; ip++) {
5981             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982             final int NA = apps.size();
5983             for (int ia=0; ia<NA; ia++) {
5984                 ProcessRecord app = apps.valueAt(ia);
5985                 if (app.persistent && !evenPersistent) {
5986                     // we don't kill persistent processes
5987                     continue;
5988                 }
5989                 if (app.removed) {
5990                     if (doit) {
5991                         procs.add(app);
5992                     }
5993                     continue;
5994                 }
5995
5996                 // Skip process if it doesn't meet our oom adj requirement.
5997                 if (app.setAdj < minOomAdj) {
5998                     continue;
5999                 }
6000
6001                 // If no package is specified, we call all processes under the
6002                 // give user id.
6003                 if (packageName == null) {
6004                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6005                         continue;
6006                     }
6007                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6008                         continue;
6009                     }
6010                 // Package has been specified, we want to hit all processes
6011                 // that match it.  We need to qualify this by the processes
6012                 // that are running under the specified app and user ID.
6013                 } else {
6014                     final boolean isDep = app.pkgDeps != null
6015                             && app.pkgDeps.contains(packageName);
6016                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6017                         continue;
6018                     }
6019                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6020                         continue;
6021                     }
6022                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6023                         continue;
6024                     }
6025                 }
6026
6027                 // Process has passed all conditions, kill it!
6028                 if (!doit) {
6029                     return true;
6030                 }
6031                 app.removed = true;
6032                 procs.add(app);
6033             }
6034         }
6035
6036         int N = procs.size();
6037         for (int i=0; i<N; i++) {
6038             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6039         }
6040         updateOomAdjLocked();
6041         return N > 0;
6042     }
6043
6044     private void cleanupDisabledPackageComponentsLocked(
6045             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6046
6047         Set<String> disabledClasses = null;
6048         boolean packageDisabled = false;
6049         IPackageManager pm = AppGlobals.getPackageManager();
6050
6051         if (changedClasses == null) {
6052             // Nothing changed...
6053             return;
6054         }
6055
6056         // Determine enable/disable state of the package and its components.
6057         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058         for (int i = changedClasses.length - 1; i >= 0; i--) {
6059             final String changedClass = changedClasses[i];
6060
6061             if (changedClass.equals(packageName)) {
6062                 try {
6063                     // Entire package setting changed
6064                     enabled = pm.getApplicationEnabledSetting(packageName,
6065                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066                 } catch (Exception e) {
6067                     // No such package/component; probably racing with uninstall.  In any
6068                     // event it means we have nothing further to do here.
6069                     return;
6070                 }
6071                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073                 if (packageDisabled) {
6074                     // Entire package is disabled.
6075                     // No need to continue to check component states.
6076                     disabledClasses = null;
6077                     break;
6078                 }
6079             } else {
6080                 try {
6081                     enabled = pm.getComponentEnabledSetting(
6082                             new ComponentName(packageName, changedClass),
6083                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084                 } catch (Exception e) {
6085                     // As above, probably racing with uninstall.
6086                     return;
6087                 }
6088                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090                     if (disabledClasses == null) {
6091                         disabledClasses = new ArraySet<>(changedClasses.length);
6092                     }
6093                     disabledClasses.add(changedClass);
6094                 }
6095             }
6096         }
6097
6098         if (!packageDisabled && disabledClasses == null) {
6099             // Nothing to do here...
6100             return;
6101         }
6102
6103         // Clean-up disabled activities.
6104         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105                 packageName, disabledClasses, true, false, userId) && mBooted) {
6106             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107             mStackSupervisor.scheduleIdleLocked();
6108         }
6109
6110         // Clean-up disabled tasks
6111         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6112
6113         // Clean-up disabled services.
6114         mServices.bringDownDisabledPackageServicesLocked(
6115                 packageName, disabledClasses, userId, false, killProcess, true);
6116
6117         // Clean-up disabled providers.
6118         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119         mProviderMap.collectPackageProvidersLocked(
6120                 packageName, disabledClasses, true, false, userId, providers);
6121         for (int i = providers.size() - 1; i >= 0; i--) {
6122             removeDyingProviderLocked(null, providers.get(i), true);
6123         }
6124
6125         // Clean-up disabled broadcast receivers.
6126         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128                     packageName, disabledClasses, userId, true);
6129         }
6130
6131     }
6132
6133     final boolean clearBroadcastQueueForUserLocked(int userId) {
6134         boolean didSomething = false;
6135         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137                     null, null, userId, true);
6138         }
6139         return didSomething;
6140     }
6141
6142     final boolean forceStopPackageLocked(String packageName, int appId,
6143             boolean callerWillRestart, boolean purgeCache, boolean doit,
6144             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6145         int i;
6146
6147         if (userId == UserHandle.USER_ALL && packageName == null) {
6148             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6149         }
6150
6151         if (appId < 0 && packageName != null) {
6152             try {
6153                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155             } catch (RemoteException e) {
6156             }
6157         }
6158
6159         if (doit) {
6160             if (packageName != null) {
6161                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162                         + " user=" + userId + ": " + reason);
6163             } else {
6164                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6165             }
6166
6167             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6168         }
6169
6170         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6173
6174         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175                 packageName, null, doit, evenPersistent, userId)) {
6176             if (!doit) {
6177                 return true;
6178             }
6179             didSomething = true;
6180         }
6181
6182         if (mServices.bringDownDisabledPackageServicesLocked(
6183                 packageName, null, userId, evenPersistent, true, doit)) {
6184             if (!doit) {
6185                 return true;
6186             }
6187             didSomething = true;
6188         }
6189
6190         if (packageName == null) {
6191             // Remove all sticky broadcasts from this user.
6192             mStickyBroadcasts.remove(userId);
6193         }
6194
6195         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197                 userId, providers)) {
6198             if (!doit) {
6199                 return true;
6200             }
6201             didSomething = true;
6202         }
6203         for (i = providers.size() - 1; i >= 0; i--) {
6204             removeDyingProviderLocked(null, providers.get(i), true);
6205         }
6206
6207         // Remove transient permissions granted from/to this package/user
6208         removeUriPermissionsForPackageLocked(packageName, userId, false);
6209
6210         if (doit) {
6211             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213                         packageName, null, userId, doit);
6214             }
6215         }
6216
6217         if (packageName == null || uninstalling) {
6218             // Remove pending intents.  For now we only do this when force
6219             // stopping users, because we have some problems when doing this
6220             // for packages -- app widgets are not currently cleaned up for
6221             // such packages, so they can be left with bad pending intents.
6222             if (mIntentSenderRecords.size() > 0) {
6223                 Iterator<WeakReference<PendingIntentRecord>> it
6224                         = mIntentSenderRecords.values().iterator();
6225                 while (it.hasNext()) {
6226                     WeakReference<PendingIntentRecord> wpir = it.next();
6227                     if (wpir == null) {
6228                         it.remove();
6229                         continue;
6230                     }
6231                     PendingIntentRecord pir = wpir.get();
6232                     if (pir == null) {
6233                         it.remove();
6234                         continue;
6235                     }
6236                     if (packageName == null) {
6237                         // Stopping user, remove all objects for the user.
6238                         if (pir.key.userId != userId) {
6239                             // Not the same user, skip it.
6240                             continue;
6241                         }
6242                     } else {
6243                         if (UserHandle.getAppId(pir.uid) != appId) {
6244                             // Different app id, skip it.
6245                             continue;
6246                         }
6247                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248                             // Different user, skip it.
6249                             continue;
6250                         }
6251                         if (!pir.key.packageName.equals(packageName)) {
6252                             // Different package, skip it.
6253                             continue;
6254                         }
6255                     }
6256                     if (!doit) {
6257                         return true;
6258                     }
6259                     didSomething = true;
6260                     it.remove();
6261                     pir.canceled = true;
6262                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263                         pir.key.activity.pendingResults.remove(pir.ref);
6264                     }
6265                 }
6266             }
6267         }
6268
6269         if (doit) {
6270             if (purgeCache && packageName != null) {
6271                 AttributeCache ac = AttributeCache.instance();
6272                 if (ac != null) {
6273                     ac.removePackage(packageName);
6274                 }
6275             }
6276             if (mBooted) {
6277                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278                 mStackSupervisor.scheduleIdleLocked();
6279             }
6280         }
6281
6282         return didSomething;
6283     }
6284
6285     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286         return removeProcessNameLocked(name, uid, null);
6287     }
6288
6289     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290             final ProcessRecord expecting) {
6291         ProcessRecord old = mProcessNames.get(name, uid);
6292         // Only actually remove when the currently recorded value matches the
6293         // record that we expected; if it doesn't match then we raced with a
6294         // newly created process and we don't want to destroy the new one.
6295         if ((expecting == null) || (old == expecting)) {
6296             mProcessNames.remove(name, uid);
6297         }
6298         if (old != null && old.uidRecord != null) {
6299             old.uidRecord.numProcs--;
6300             if (old.uidRecord.numProcs == 0) {
6301                 // No more processes using this uid, tell clients it is gone.
6302                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303                         "No more processes in " + old.uidRecord);
6304                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305                 mActiveUids.remove(uid);
6306                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6307             }
6308             old.uidRecord = null;
6309         }
6310         mIsolatedProcesses.remove(uid);
6311         return old;
6312     }
6313
6314     private final void addProcessNameLocked(ProcessRecord proc) {
6315         // We shouldn't already have a process under this name, but just in case we
6316         // need to clean up whatever may be there now.
6317         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318         if (old == proc && proc.persistent) {
6319             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6320             Slog.w(TAG, "Re-adding persistent process " + proc);
6321         } else if (old != null) {
6322             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6323         }
6324         UidRecord uidRec = mActiveUids.get(proc.uid);
6325         if (uidRec == null) {
6326             uidRec = new UidRecord(proc.uid);
6327             // This is the first appearance of the uid, report it now!
6328             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329                     "Creating new process uid: " + uidRec);
6330             mActiveUids.put(proc.uid, uidRec);
6331             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6333         }
6334         proc.uidRecord = uidRec;
6335
6336         // Reset render thread tid if it was already set, so new process can set it again.
6337         proc.renderThreadTid = 0;
6338         uidRec.numProcs++;
6339         mProcessNames.put(proc.processName, proc.uid, proc);
6340         if (proc.isolated) {
6341             mIsolatedProcesses.put(proc.uid, proc);
6342         }
6343     }
6344
6345     boolean removeProcessLocked(ProcessRecord app,
6346             boolean callerWillRestart, boolean allowRestart, String reason) {
6347         final String name = app.processName;
6348         final int uid = app.uid;
6349         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6351
6352         ProcessRecord old = mProcessNames.get(name, uid);
6353         if (old != app) {
6354             // This process is no longer active, so nothing to do.
6355             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6356             return false;
6357         }
6358         removeProcessNameLocked(name, uid);
6359         if (mHeavyWeightProcess == app) {
6360             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361                     mHeavyWeightProcess.userId, 0));
6362             mHeavyWeightProcess = null;
6363         }
6364         boolean needRestart = false;
6365         if (app.pid > 0 && app.pid != MY_PID) {
6366             int pid = app.pid;
6367             synchronized (mPidsSelfLocked) {
6368                 mPidsSelfLocked.remove(pid);
6369                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6370             }
6371             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6372             if (app.isolated) {
6373                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6374             }
6375             boolean willRestart = false;
6376             if (app.persistent && !app.isolated) {
6377                 if (!callerWillRestart) {
6378                     willRestart = true;
6379                 } else {
6380                     needRestart = true;
6381                 }
6382             }
6383             app.kill(reason, true);
6384             handleAppDiedLocked(app, willRestart, allowRestart);
6385             if (willRestart) {
6386                 removeLruProcessLocked(app);
6387                 addAppLocked(app.info, false, null /* ABI override */);
6388             }
6389         } else {
6390             mRemovedProcesses.add(app);
6391         }
6392
6393         return needRestart;
6394     }
6395
6396     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397         cleanupAppInLaunchingProvidersLocked(app, true);
6398         removeProcessLocked(app, false, true, "timeout publishing content providers");
6399     }
6400
6401     private final void processStartTimedOutLocked(ProcessRecord app) {
6402         final int pid = app.pid;
6403         boolean gone = false;
6404         synchronized (mPidsSelfLocked) {
6405             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406             if (knownApp != null && knownApp.thread == null) {
6407                 mPidsSelfLocked.remove(pid);
6408                 gone = true;
6409             }
6410         }
6411
6412         if (gone) {
6413             Slog.w(TAG, "Process " + app + " failed to attach");
6414             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415                     pid, app.uid, app.processName);
6416             removeProcessNameLocked(app.processName, app.uid);
6417             if (mHeavyWeightProcess == app) {
6418                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419                         mHeavyWeightProcess.userId, 0));
6420                 mHeavyWeightProcess = null;
6421             }
6422             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6423             if (app.isolated) {
6424                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6425             }
6426             // Take care of any launching providers waiting for this process.
6427             cleanupAppInLaunchingProvidersLocked(app, true);
6428             // Take care of any services that are waiting for the process.
6429             mServices.processStartTimedOutLocked(app);
6430             app.kill("start timeout", true);
6431             removeLruProcessLocked(app);
6432             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433                 Slog.w(TAG, "Unattached app died before backup, skipping");
6434                 try {
6435                     IBackupManager bm = IBackupManager.Stub.asInterface(
6436                             ServiceManager.getService(Context.BACKUP_SERVICE));
6437                     bm.agentDisconnected(app.info.packageName);
6438                 } catch (RemoteException e) {
6439                     // Can't happen; the backup manager is local
6440                 }
6441             }
6442             if (isPendingBroadcastProcessLocked(pid)) {
6443                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444                 skipPendingBroadcastLocked(pid);
6445             }
6446         } else {
6447             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6448         }
6449     }
6450
6451     private final boolean attachApplicationLocked(IApplicationThread thread,
6452             int pid) {
6453
6454         // Find the application record that is being attached...  either via
6455         // the pid if we are running in multiple processes, or just pull the
6456         // next app record if we are emulating process with anonymous threads.
6457         ProcessRecord app;
6458         if (pid != MY_PID && pid >= 0) {
6459             synchronized (mPidsSelfLocked) {
6460                 app = mPidsSelfLocked.get(pid);
6461             }
6462         } else {
6463             app = null;
6464         }
6465
6466         if (app == null) {
6467             Slog.w(TAG, "No pending application record for pid " + pid
6468                     + " (IApplicationThread " + thread + "); dropping process");
6469             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6470             if (pid > 0 && pid != MY_PID) {
6471                 Process.killProcessQuiet(pid);
6472                 //TODO: killProcessGroup(app.info.uid, pid);
6473             } else {
6474                 try {
6475                     thread.scheduleExit();
6476                 } catch (Exception e) {
6477                     // Ignore exceptions.
6478                 }
6479             }
6480             return false;
6481         }
6482
6483         // If this application record is still attached to a previous
6484         // process, clean it up now.
6485         if (app.thread != null) {
6486             handleAppDiedLocked(app, true, true);
6487         }
6488
6489         // Tell the process all about itself.
6490
6491         if (DEBUG_ALL) Slog.v(
6492                 TAG, "Binding process pid " + pid + " to record " + app);
6493
6494         final String processName = app.processName;
6495         try {
6496             AppDeathRecipient adr = new AppDeathRecipient(
6497                     app, pid, thread);
6498             thread.asBinder().linkToDeath(adr, 0);
6499             app.deathRecipient = adr;
6500         } catch (RemoteException e) {
6501             app.resetPackageList(mProcessStats);
6502             startProcessLocked(app, "link fail", processName);
6503             return false;
6504         }
6505
6506         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6507
6508         app.makeActive(thread, mProcessStats);
6509         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6510         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6511         app.forcingToForeground = null;
6512         updateProcessForegroundLocked(app, false, false);
6513         app.hasShownUi = false;
6514         app.debugging = false;
6515         app.cached = false;
6516         app.killedByAm = false;
6517
6518         // We carefully use the same state that PackageManager uses for
6519         // filtering, since we use this flag to decide if we need to install
6520         // providers when user is unlocked later
6521         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6522
6523         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6524
6525         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6526         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6527
6528         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6529             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6530             msg.obj = app;
6531             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6532         }
6533
6534         if (!normalMode) {
6535             Slog.i(TAG, "Launching preboot mode app: " + app);
6536         }
6537
6538         if (DEBUG_ALL) Slog.v(
6539             TAG, "New app record " + app
6540             + " thread=" + thread.asBinder() + " pid=" + pid);
6541         try {
6542             int testMode = IApplicationThread.DEBUG_OFF;
6543             if (mDebugApp != null && mDebugApp.equals(processName)) {
6544                 testMode = mWaitForDebugger
6545                     ? IApplicationThread.DEBUG_WAIT
6546                     : IApplicationThread.DEBUG_ON;
6547                 app.debugging = true;
6548                 if (mDebugTransient) {
6549                     mDebugApp = mOrigDebugApp;
6550                     mWaitForDebugger = mOrigWaitForDebugger;
6551                 }
6552             }
6553             String profileFile = app.instrumentationProfileFile;
6554             ParcelFileDescriptor profileFd = null;
6555             int samplingInterval = 0;
6556             boolean profileAutoStop = false;
6557             if (mProfileApp != null && mProfileApp.equals(processName)) {
6558                 mProfileProc = app;
6559                 profileFile = mProfileFile;
6560                 profileFd = mProfileFd;
6561                 samplingInterval = mSamplingInterval;
6562                 profileAutoStop = mAutoStopProfiler;
6563             }
6564             boolean enableTrackAllocation = false;
6565             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6566                 enableTrackAllocation = true;
6567                 mTrackAllocationApp = null;
6568             }
6569
6570             // If the app is being launched for restore or full backup, set it up specially
6571             boolean isRestrictedBackupMode = false;
6572             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6573                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6574                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6575                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6576                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6577             }
6578
6579             if (app.instrumentationClass != null) {
6580                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6581                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6582             }
6583             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6584                     + processName + " with config " + mConfiguration);
6585             ApplicationInfo appInfo = app.instrumentationInfo != null
6586                     ? app.instrumentationInfo : app.info;
6587             app.compat = compatibilityInfoForPackageLocked(appInfo);
6588             if (profileFd != null) {
6589                 profileFd = profileFd.dup();
6590             }
6591             ProfilerInfo profilerInfo = profileFile == null ? null
6592                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6593             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6594                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6595                     app.instrumentationUiAutomationConnection, testMode,
6596                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6597                     isRestrictedBackupMode || !normalMode, app.persistent,
6598                     new Configuration(mConfiguration), app.compat,
6599                     getCommonServicesLocked(app.isolated),
6600                     mCoreSettingsObserver.getCoreSettingsLocked());
6601             updateLruProcessLocked(app, false, null);
6602             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6603         } catch (Exception e) {
6604             // todo: Yikes!  What should we do?  For now we will try to
6605             // start another process, but that could easily get us in
6606             // an infinite loop of restarting processes...
6607             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6608
6609             app.resetPackageList(mProcessStats);
6610             app.unlinkDeathRecipient();
6611             startProcessLocked(app, "bind fail", processName);
6612             return false;
6613         }
6614
6615         // Remove this record from the list of starting applications.
6616         mPersistentStartingProcesses.remove(app);
6617         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6618                 "Attach application locked removing on hold: " + app);
6619         mProcessesOnHold.remove(app);
6620
6621         boolean badApp = false;
6622         boolean didSomething = false;
6623
6624         // See if the top visible activity is waiting to run in this process...
6625         if (normalMode) {
6626             try {
6627                 if (mStackSupervisor.attachApplicationLocked(app)) {
6628                     didSomething = true;
6629                 }
6630             } catch (Exception e) {
6631                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6632                 badApp = true;
6633             }
6634         }
6635
6636         // Find any services that should be running in this process...
6637         if (!badApp) {
6638             try {
6639                 didSomething |= mServices.attachApplicationLocked(app, processName);
6640             } catch (Exception e) {
6641                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6642                 badApp = true;
6643             }
6644         }
6645
6646         // Check if a next-broadcast receiver is in this process...
6647         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6648             try {
6649                 didSomething |= sendPendingBroadcastsLocked(app);
6650             } catch (Exception e) {
6651                 // If the app died trying to launch the receiver we declare it 'bad'
6652                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6653                 badApp = true;
6654             }
6655         }
6656
6657         // Check whether the next backup agent is in this process...
6658         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6659             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6660                     "New app is backup target, launching agent for " + app);
6661             notifyPackageUse(mBackupTarget.appInfo.packageName,
6662                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6663             try {
6664                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6665                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6666                         mBackupTarget.backupMode);
6667             } catch (Exception e) {
6668                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6669                 badApp = true;
6670             }
6671         }
6672
6673         if (badApp) {
6674             app.kill("error during init", true);
6675             handleAppDiedLocked(app, false, true);
6676             return false;
6677         }
6678
6679         if (!didSomething) {
6680             updateOomAdjLocked();
6681         }
6682
6683         return true;
6684     }
6685
6686     @Override
6687     public final void attachApplication(IApplicationThread thread) {
6688         synchronized (this) {
6689             int callingPid = Binder.getCallingPid();
6690             final long origId = Binder.clearCallingIdentity();
6691             attachApplicationLocked(thread, callingPid);
6692             Binder.restoreCallingIdentity(origId);
6693         }
6694     }
6695
6696     @Override
6697     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6698         final long origId = Binder.clearCallingIdentity();
6699         synchronized (this) {
6700             ActivityStack stack = ActivityRecord.getStackLocked(token);
6701             if (stack != null) {
6702                 ActivityRecord r =
6703                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6704                 if (stopProfiling) {
6705                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6706                         try {
6707                             mProfileFd.close();
6708                         } catch (IOException e) {
6709                         }
6710                         clearProfilerLocked();
6711                     }
6712                 }
6713             }
6714         }
6715         Binder.restoreCallingIdentity(origId);
6716     }
6717
6718     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6719         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6720                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6721     }
6722
6723     void enableScreenAfterBoot() {
6724         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6725                 SystemClock.uptimeMillis());
6726         mWindowManager.enableScreenAfterBoot();
6727
6728         synchronized (this) {
6729             updateEventDispatchingLocked();
6730         }
6731     }
6732
6733     @Override
6734     public void showBootMessage(final CharSequence msg, final boolean always) {
6735         if (Binder.getCallingUid() != Process.myUid()) {
6736             throw new SecurityException();
6737         }
6738         mWindowManager.showBootMessage(msg, always);
6739     }
6740
6741     @Override
6742     public void keyguardWaitingForActivityDrawn() {
6743         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6744         final long token = Binder.clearCallingIdentity();
6745         try {
6746             synchronized (this) {
6747                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6748                 mWindowManager.keyguardWaitingForActivityDrawn();
6749                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6750                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6751                     updateSleepIfNeededLocked();
6752                 }
6753             }
6754         } finally {
6755             Binder.restoreCallingIdentity(token);
6756         }
6757     }
6758
6759     @Override
6760     public void keyguardGoingAway(int flags) {
6761         enforceNotIsolatedCaller("keyguardGoingAway");
6762         final long token = Binder.clearCallingIdentity();
6763         try {
6764             synchronized (this) {
6765                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6766                 mWindowManager.keyguardGoingAway(flags);
6767                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6768                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6769                     updateSleepIfNeededLocked();
6770
6771                     // Some stack visibility might change (e.g. docked stack)
6772                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6773                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6774                 }
6775             }
6776         } finally {
6777             Binder.restoreCallingIdentity(token);
6778         }
6779     }
6780
6781     final void finishBooting() {
6782         synchronized (this) {
6783             if (!mBootAnimationComplete) {
6784                 mCallFinishBooting = true;
6785                 return;
6786             }
6787             mCallFinishBooting = false;
6788         }
6789
6790         ArraySet<String> completedIsas = new ArraySet<String>();
6791         for (String abi : Build.SUPPORTED_ABIS) {
6792             Process.establishZygoteConnectionForAbi(abi);
6793             final String instructionSet = VMRuntime.getInstructionSet(abi);
6794             if (!completedIsas.contains(instructionSet)) {
6795                 try {
6796                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6797                 } catch (InstallerException e) {
6798                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6799                             e.getMessage() +")");
6800                 }
6801                 completedIsas.add(instructionSet);
6802             }
6803         }
6804
6805         IntentFilter pkgFilter = new IntentFilter();
6806         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6807         pkgFilter.addDataScheme("package");
6808         mContext.registerReceiver(new BroadcastReceiver() {
6809             @Override
6810             public void onReceive(Context context, Intent intent) {
6811                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6812                 if (pkgs != null) {
6813                     for (String pkg : pkgs) {
6814                         synchronized (ActivityManagerService.this) {
6815                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6816                                     0, "query restart")) {
6817                                 setResultCode(Activity.RESULT_OK);
6818                                 return;
6819                             }
6820                         }
6821                     }
6822                 }
6823             }
6824         }, pkgFilter);
6825
6826         IntentFilter dumpheapFilter = new IntentFilter();
6827         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6828         mContext.registerReceiver(new BroadcastReceiver() {
6829             @Override
6830             public void onReceive(Context context, Intent intent) {
6831                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6832                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6833                 } else {
6834                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6835                 }
6836             }
6837         }, dumpheapFilter);
6838
6839         // Let system services know.
6840         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6841
6842         synchronized (this) {
6843             // Ensure that any processes we had put on hold are now started
6844             // up.
6845             final int NP = mProcessesOnHold.size();
6846             if (NP > 0) {
6847                 ArrayList<ProcessRecord> procs =
6848                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6849                 for (int ip=0; ip<NP; ip++) {
6850                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6851                             + procs.get(ip));
6852                     startProcessLocked(procs.get(ip), "on-hold", null);
6853                 }
6854             }
6855
6856             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6857                 // Start looking for apps that are abusing wake locks.
6858                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6859                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6860                 // Tell anyone interested that we are done booting!
6861                 SystemProperties.set("sys.boot_completed", "1");
6862
6863                 // And trigger dev.bootcomplete if we are not showing encryption progress
6864                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6865                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6866                     SystemProperties.set("dev.bootcomplete", "1");
6867                 }
6868                 mUserController.sendBootCompletedLocked(
6869                         new IIntentReceiver.Stub() {
6870                             @Override
6871                             public void performReceive(Intent intent, int resultCode,
6872                                     String data, Bundle extras, boolean ordered,
6873                                     boolean sticky, int sendingUser) {
6874                                 synchronized (ActivityManagerService.this) {
6875                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6876                                             true, false);
6877                                 }
6878                             }
6879                         });
6880                 scheduleStartProfilesLocked();
6881             }
6882         }
6883     }
6884
6885     @Override
6886     public void bootAnimationComplete() {
6887         final boolean callFinishBooting;
6888         synchronized (this) {
6889             callFinishBooting = mCallFinishBooting;
6890             mBootAnimationComplete = true;
6891         }
6892         if (callFinishBooting) {
6893             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6894             finishBooting();
6895             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6896         }
6897     }
6898
6899     final void ensureBootCompleted() {
6900         boolean booting;
6901         boolean enableScreen;
6902         synchronized (this) {
6903             booting = mBooting;
6904             mBooting = false;
6905             enableScreen = !mBooted;
6906             mBooted = true;
6907         }
6908
6909         if (booting) {
6910             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6911             finishBooting();
6912             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6913         }
6914
6915         if (enableScreen) {
6916             enableScreenAfterBoot();
6917         }
6918     }
6919
6920     @Override
6921     public final void activityResumed(IBinder token) {
6922         final long origId = Binder.clearCallingIdentity();
6923         synchronized(this) {
6924             ActivityStack stack = ActivityRecord.getStackLocked(token);
6925             if (stack != null) {
6926                 stack.activityResumedLocked(token);
6927             }
6928         }
6929         Binder.restoreCallingIdentity(origId);
6930     }
6931
6932     @Override
6933     public final void activityPaused(IBinder token) {
6934         final long origId = Binder.clearCallingIdentity();
6935         synchronized(this) {
6936             ActivityStack stack = ActivityRecord.getStackLocked(token);
6937             if (stack != null) {
6938                 stack.activityPausedLocked(token, false);
6939             }
6940         }
6941         Binder.restoreCallingIdentity(origId);
6942     }
6943
6944     @Override
6945     public final void activityStopped(IBinder token, Bundle icicle,
6946             PersistableBundle persistentState, CharSequence description) {
6947         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6948
6949         // Refuse possible leaked file descriptors
6950         if (icicle != null && icicle.hasFileDescriptors()) {
6951             throw new IllegalArgumentException("File descriptors passed in Bundle");
6952         }
6953
6954         final long origId = Binder.clearCallingIdentity();
6955
6956         synchronized (this) {
6957             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6958             if (r != null) {
6959                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6960             }
6961         }
6962
6963         trimApplications();
6964
6965         Binder.restoreCallingIdentity(origId);
6966     }
6967
6968     @Override
6969     public final void activityDestroyed(IBinder token) {
6970         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6971         synchronized (this) {
6972             ActivityStack stack = ActivityRecord.getStackLocked(token);
6973             if (stack != null) {
6974                 stack.activityDestroyedLocked(token, "activityDestroyed");
6975             }
6976         }
6977     }
6978
6979     @Override
6980     public final void activityRelaunched(IBinder token) {
6981         final long origId = Binder.clearCallingIdentity();
6982         synchronized (this) {
6983             mStackSupervisor.activityRelaunchedLocked(token);
6984         }
6985         Binder.restoreCallingIdentity(origId);
6986     }
6987
6988     @Override
6989     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6990             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6991         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6992                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6993         synchronized (this) {
6994             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6995             if (record == null) {
6996                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6997                         + "found for: " + token);
6998             }
6999             record.setSizeConfigurations(horizontalSizeConfiguration,
7000                     verticalSizeConfigurations, smallestSizeConfigurations);
7001         }
7002     }
7003
7004     @Override
7005     public final void backgroundResourcesReleased(IBinder token) {
7006         final long origId = Binder.clearCallingIdentity();
7007         try {
7008             synchronized (this) {
7009                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7010                 if (stack != null) {
7011                     stack.backgroundResourcesReleased();
7012                 }
7013             }
7014         } finally {
7015             Binder.restoreCallingIdentity(origId);
7016         }
7017     }
7018
7019     @Override
7020     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7021         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7022     }
7023
7024     @Override
7025     public final void notifyEnterAnimationComplete(IBinder token) {
7026         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7027     }
7028
7029     @Override
7030     public String getCallingPackage(IBinder token) {
7031         synchronized (this) {
7032             ActivityRecord r = getCallingRecordLocked(token);
7033             return r != null ? r.info.packageName : null;
7034         }
7035     }
7036
7037     @Override
7038     public ComponentName getCallingActivity(IBinder token) {
7039         synchronized (this) {
7040             ActivityRecord r = getCallingRecordLocked(token);
7041             return r != null ? r.intent.getComponent() : null;
7042         }
7043     }
7044
7045     private ActivityRecord getCallingRecordLocked(IBinder token) {
7046         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7047         if (r == null) {
7048             return null;
7049         }
7050         return r.resultTo;
7051     }
7052
7053     @Override
7054     public ComponentName getActivityClassForToken(IBinder token) {
7055         synchronized(this) {
7056             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7057             if (r == null) {
7058                 return null;
7059             }
7060             return r.intent.getComponent();
7061         }
7062     }
7063
7064     @Override
7065     public String getPackageForToken(IBinder token) {
7066         synchronized(this) {
7067             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7068             if (r == null) {
7069                 return null;
7070             }
7071             return r.packageName;
7072         }
7073     }
7074
7075     @Override
7076     public boolean isRootVoiceInteraction(IBinder token) {
7077         synchronized(this) {
7078             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079             if (r == null) {
7080                 return false;
7081             }
7082             return r.rootVoiceInteraction;
7083         }
7084     }
7085
7086     @Override
7087     public IIntentSender getIntentSender(int type,
7088             String packageName, IBinder token, String resultWho,
7089             int requestCode, Intent[] intents, String[] resolvedTypes,
7090             int flags, Bundle bOptions, int userId) {
7091         enforceNotIsolatedCaller("getIntentSender");
7092         // Refuse possible leaked file descriptors
7093         if (intents != null) {
7094             if (intents.length < 1) {
7095                 throw new IllegalArgumentException("Intents array length must be >= 1");
7096             }
7097             for (int i=0; i<intents.length; i++) {
7098                 Intent intent = intents[i];
7099                 if (intent != null) {
7100                     if (intent.hasFileDescriptors()) {
7101                         throw new IllegalArgumentException("File descriptors passed in Intent");
7102                     }
7103                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7104                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7105                         throw new IllegalArgumentException(
7106                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7107                     }
7108                     intents[i] = new Intent(intent);
7109                 }
7110             }
7111             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7112                 throw new IllegalArgumentException(
7113                         "Intent array length does not match resolvedTypes length");
7114             }
7115         }
7116         if (bOptions != null) {
7117             if (bOptions.hasFileDescriptors()) {
7118                 throw new IllegalArgumentException("File descriptors passed in options");
7119             }
7120         }
7121
7122         synchronized(this) {
7123             int callingUid = Binder.getCallingUid();
7124             int origUserId = userId;
7125             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7126                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7127                     ALLOW_NON_FULL, "getIntentSender", null);
7128             if (origUserId == UserHandle.USER_CURRENT) {
7129                 // We don't want to evaluate this until the pending intent is
7130                 // actually executed.  However, we do want to always do the
7131                 // security checking for it above.
7132                 userId = UserHandle.USER_CURRENT;
7133             }
7134             try {
7135                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7136                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7137                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7138                     if (!UserHandle.isSameApp(callingUid, uid)) {
7139                         String msg = "Permission Denial: getIntentSender() from pid="
7140                             + Binder.getCallingPid()
7141                             + ", uid=" + Binder.getCallingUid()
7142                             + ", (need uid=" + uid + ")"
7143                             + " is not allowed to send as package " + packageName;
7144                         Slog.w(TAG, msg);
7145                         throw new SecurityException(msg);
7146                     }
7147                 }
7148
7149                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7150                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7151
7152             } catch (RemoteException e) {
7153                 throw new SecurityException(e);
7154             }
7155         }
7156     }
7157
7158     IIntentSender getIntentSenderLocked(int type, String packageName,
7159             int callingUid, int userId, IBinder token, String resultWho,
7160             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7161             Bundle bOptions) {
7162         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7163         ActivityRecord activity = null;
7164         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7165             activity = ActivityRecord.isInStackLocked(token);
7166             if (activity == null) {
7167                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7168                 return null;
7169             }
7170             if (activity.finishing) {
7171                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7172                 return null;
7173             }
7174         }
7175
7176         // We're going to be splicing together extras before sending, so we're
7177         // okay poking into any contained extras.
7178         if (intents != null) {
7179             for (int i = 0; i < intents.length; i++) {
7180                 intents[i].setDefusable(true);
7181             }
7182         }
7183         Bundle.setDefusable(bOptions, true);
7184
7185         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7186         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7187         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7188         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7189                 |PendingIntent.FLAG_UPDATE_CURRENT);
7190
7191         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7192                 type, packageName, activity, resultWho,
7193                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7194         WeakReference<PendingIntentRecord> ref;
7195         ref = mIntentSenderRecords.get(key);
7196         PendingIntentRecord rec = ref != null ? ref.get() : null;
7197         if (rec != null) {
7198             if (!cancelCurrent) {
7199                 if (updateCurrent) {
7200                     if (rec.key.requestIntent != null) {
7201                         rec.key.requestIntent.replaceExtras(intents != null ?
7202                                 intents[intents.length - 1] : null);
7203                     }
7204                     if (intents != null) {
7205                         intents[intents.length-1] = rec.key.requestIntent;
7206                         rec.key.allIntents = intents;
7207                         rec.key.allResolvedTypes = resolvedTypes;
7208                     } else {
7209                         rec.key.allIntents = null;
7210                         rec.key.allResolvedTypes = null;
7211                     }
7212                 }
7213                 return rec;
7214             }
7215             rec.canceled = true;
7216             mIntentSenderRecords.remove(key);
7217         }
7218         if (noCreate) {
7219             return rec;
7220         }
7221         rec = new PendingIntentRecord(this, key, callingUid);
7222         mIntentSenderRecords.put(key, rec.ref);
7223         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7224             if (activity.pendingResults == null) {
7225                 activity.pendingResults
7226                         = new HashSet<WeakReference<PendingIntentRecord>>();
7227             }
7228             activity.pendingResults.add(rec.ref);
7229         }
7230         return rec;
7231     }
7232
7233     @Override
7234     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7235             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7236         if (target instanceof PendingIntentRecord) {
7237             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7238                     finishedReceiver, requiredPermission, options);
7239         } else {
7240             if (intent == null) {
7241                 // Weird case: someone has given us their own custom IIntentSender, and now
7242                 // they have someone else trying to send to it but of course this isn't
7243                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7244                 // supplying an Intent... but we never want to dispatch a null Intent to
7245                 // a receiver, so um...  let's make something up.
7246                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7247                 intent = new Intent(Intent.ACTION_MAIN);
7248             }
7249             try {
7250                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7251             } catch (RemoteException e) {
7252             }
7253             // Platform code can rely on getting a result back when the send is done, but if
7254             // this intent sender is from outside of the system we can't rely on it doing that.
7255             // So instead we don't give it the result receiver, and instead just directly
7256             // report the finish immediately.
7257             if (finishedReceiver != null) {
7258                 try {
7259                     finishedReceiver.performReceive(intent, 0,
7260                             null, null, false, false, UserHandle.getCallingUserId());
7261                 } catch (RemoteException e) {
7262                 }
7263             }
7264             return 0;
7265         }
7266     }
7267
7268     /**
7269      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7270      *
7271      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7272      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7273      */
7274     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7275         if (DEBUG_WHITELISTS) {
7276             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7277                     + targetUid + ", " + duration + ")");
7278         }
7279         synchronized (mPidsSelfLocked) {
7280             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7281             if (pr == null) {
7282                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7283                 return;
7284             }
7285             if (!pr.whitelistManager) {
7286                 if (DEBUG_WHITELISTS) {
7287                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7288                             + callerPid + " is not allowed");
7289                 }
7290                 return;
7291             }
7292         }
7293
7294         final long token = Binder.clearCallingIdentity();
7295         try {
7296             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7297                     true, "pe from uid:" + callerUid);
7298         } finally {
7299             Binder.restoreCallingIdentity(token);
7300         }
7301     }
7302
7303     @Override
7304     public void cancelIntentSender(IIntentSender sender) {
7305         if (!(sender instanceof PendingIntentRecord)) {
7306             return;
7307         }
7308         synchronized(this) {
7309             PendingIntentRecord rec = (PendingIntentRecord)sender;
7310             try {
7311                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7312                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7313                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7314                     String msg = "Permission Denial: cancelIntentSender() from pid="
7315                         + Binder.getCallingPid()
7316                         + ", uid=" + Binder.getCallingUid()
7317                         + " is not allowed to cancel packges "
7318                         + rec.key.packageName;
7319                     Slog.w(TAG, msg);
7320                     throw new SecurityException(msg);
7321                 }
7322             } catch (RemoteException e) {
7323                 throw new SecurityException(e);
7324             }
7325             cancelIntentSenderLocked(rec, true);
7326         }
7327     }
7328
7329     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7330         rec.canceled = true;
7331         mIntentSenderRecords.remove(rec.key);
7332         if (cleanActivity && rec.key.activity != null) {
7333             rec.key.activity.pendingResults.remove(rec.ref);
7334         }
7335     }
7336
7337     @Override
7338     public String getPackageForIntentSender(IIntentSender pendingResult) {
7339         if (!(pendingResult instanceof PendingIntentRecord)) {
7340             return null;
7341         }
7342         try {
7343             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344             return res.key.packageName;
7345         } catch (ClassCastException e) {
7346         }
7347         return null;
7348     }
7349
7350     @Override
7351     public int getUidForIntentSender(IIntentSender sender) {
7352         if (sender instanceof PendingIntentRecord) {
7353             try {
7354                 PendingIntentRecord res = (PendingIntentRecord)sender;
7355                 return res.uid;
7356             } catch (ClassCastException e) {
7357             }
7358         }
7359         return -1;
7360     }
7361
7362     @Override
7363     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7364         if (!(pendingResult instanceof PendingIntentRecord)) {
7365             return false;
7366         }
7367         try {
7368             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7369             if (res.key.allIntents == null) {
7370                 return false;
7371             }
7372             for (int i=0; i<res.key.allIntents.length; i++) {
7373                 Intent intent = res.key.allIntents[i];
7374                 if (intent.getPackage() != null && intent.getComponent() != null) {
7375                     return false;
7376                 }
7377             }
7378             return true;
7379         } catch (ClassCastException e) {
7380         }
7381         return false;
7382     }
7383
7384     @Override
7385     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7386         if (!(pendingResult instanceof PendingIntentRecord)) {
7387             return false;
7388         }
7389         try {
7390             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7391             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7392                 return true;
7393             }
7394             return false;
7395         } catch (ClassCastException e) {
7396         }
7397         return false;
7398     }
7399
7400     @Override
7401     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7402         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7403                 "getIntentForIntentSender()");
7404         if (!(pendingResult instanceof PendingIntentRecord)) {
7405             return null;
7406         }
7407         try {
7408             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7410         } catch (ClassCastException e) {
7411         }
7412         return null;
7413     }
7414
7415     @Override
7416     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7417         if (!(pendingResult instanceof PendingIntentRecord)) {
7418             return null;
7419         }
7420         try {
7421             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7422             synchronized (this) {
7423                 return getTagForIntentSenderLocked(res, prefix);
7424             }
7425         } catch (ClassCastException e) {
7426         }
7427         return null;
7428     }
7429
7430     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7431         final Intent intent = res.key.requestIntent;
7432         if (intent != null) {
7433             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7434                     || res.lastTagPrefix.equals(prefix))) {
7435                 return res.lastTag;
7436             }
7437             res.lastTagPrefix = prefix;
7438             final StringBuilder sb = new StringBuilder(128);
7439             if (prefix != null) {
7440                 sb.append(prefix);
7441             }
7442             if (intent.getAction() != null) {
7443                 sb.append(intent.getAction());
7444             } else if (intent.getComponent() != null) {
7445                 intent.getComponent().appendShortString(sb);
7446             } else {
7447                 sb.append("?");
7448             }
7449             return res.lastTag = sb.toString();
7450         }
7451         return null;
7452     }
7453
7454     @Override
7455     public void setProcessLimit(int max) {
7456         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7457                 "setProcessLimit()");
7458         synchronized (this) {
7459             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7460             mProcessLimitOverride = max;
7461         }
7462         trimApplications();
7463     }
7464
7465     @Override
7466     public int getProcessLimit() {
7467         synchronized (this) {
7468             return mProcessLimitOverride;
7469         }
7470     }
7471
7472     void foregroundTokenDied(ForegroundToken token) {
7473         synchronized (ActivityManagerService.this) {
7474             synchronized (mPidsSelfLocked) {
7475                 ForegroundToken cur
7476                     = mForegroundProcesses.get(token.pid);
7477                 if (cur != token) {
7478                     return;
7479                 }
7480                 mForegroundProcesses.remove(token.pid);
7481                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7482                 if (pr == null) {
7483                     return;
7484                 }
7485                 pr.forcingToForeground = null;
7486                 updateProcessForegroundLocked(pr, false, false);
7487             }
7488             updateOomAdjLocked();
7489         }
7490     }
7491
7492     @Override
7493     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7494         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7495                 "setProcessForeground()");
7496         synchronized(this) {
7497             boolean changed = false;
7498
7499             synchronized (mPidsSelfLocked) {
7500                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7501                 if (pr == null && isForeground) {
7502                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7503                     return;
7504                 }
7505                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7506                 if (oldToken != null) {
7507                     oldToken.token.unlinkToDeath(oldToken, 0);
7508                     mForegroundProcesses.remove(pid);
7509                     if (pr != null) {
7510                         pr.forcingToForeground = null;
7511                     }
7512                     changed = true;
7513                 }
7514                 if (isForeground && token != null) {
7515                     ForegroundToken newToken = new ForegroundToken() {
7516                         @Override
7517                         public void binderDied() {
7518                             foregroundTokenDied(this);
7519                         }
7520                     };
7521                     newToken.pid = pid;
7522                     newToken.token = token;
7523                     try {
7524                         token.linkToDeath(newToken, 0);
7525                         mForegroundProcesses.put(pid, newToken);
7526                         pr.forcingToForeground = token;
7527                         changed = true;
7528                     } catch (RemoteException e) {
7529                         // If the process died while doing this, we will later
7530                         // do the cleanup with the process death link.
7531                     }
7532                 }
7533             }
7534
7535             if (changed) {
7536                 updateOomAdjLocked();
7537             }
7538         }
7539     }
7540
7541     @Override
7542     public boolean isAppForeground(int uid) throws RemoteException {
7543         synchronized (this) {
7544             UidRecord uidRec = mActiveUids.get(uid);
7545             if (uidRec == null || uidRec.idle) {
7546                 return false;
7547             }
7548             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7549         }
7550     }
7551
7552     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7553     // be guarded by permission checking.
7554     int getUidState(int uid) {
7555         synchronized (this) {
7556             UidRecord uidRec = mActiveUids.get(uid);
7557             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7558         }
7559     }
7560
7561     @Override
7562     public boolean isInMultiWindowMode(IBinder token) {
7563         final long origId = Binder.clearCallingIdentity();
7564         try {
7565             synchronized(this) {
7566                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567                 if (r == null) {
7568                     return false;
7569                 }
7570                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7571                 return !r.task.mFullscreen;
7572             }
7573         } finally {
7574             Binder.restoreCallingIdentity(origId);
7575         }
7576     }
7577
7578     @Override
7579     public boolean isInPictureInPictureMode(IBinder token) {
7580         final long origId = Binder.clearCallingIdentity();
7581         try {
7582             synchronized(this) {
7583                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7584                 if (stack == null) {
7585                     return false;
7586                 }
7587                 return stack.mStackId == PINNED_STACK_ID;
7588             }
7589         } finally {
7590             Binder.restoreCallingIdentity(origId);
7591         }
7592     }
7593
7594     @Override
7595     public void enterPictureInPictureMode(IBinder token) {
7596         final long origId = Binder.clearCallingIdentity();
7597         try {
7598             synchronized(this) {
7599                 if (!mSupportsPictureInPicture) {
7600                     throw new IllegalStateException("enterPictureInPictureMode: "
7601                             + "Device doesn't support picture-in-picture mode.");
7602                 }
7603
7604                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7605
7606                 if (r == null) {
7607                     throw new IllegalStateException("enterPictureInPictureMode: "
7608                             + "Can't find activity for token=" + token);
7609                 }
7610
7611                 if (!r.supportsPictureInPicture()) {
7612                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7613                             + "Picture-In-Picture not supported for r=" + r);
7614                 }
7615
7616                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7617                 // current bounds.
7618                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7619                 final Rect bounds = (pinnedStack != null)
7620                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7621
7622                 mStackSupervisor.moveActivityToPinnedStackLocked(
7623                         r, "enterPictureInPictureMode", bounds);
7624             }
7625         } finally {
7626             Binder.restoreCallingIdentity(origId);
7627         }
7628     }
7629
7630     // =========================================================
7631     // PROCESS INFO
7632     // =========================================================
7633
7634     static class ProcessInfoService extends IProcessInfoService.Stub {
7635         final ActivityManagerService mActivityManagerService;
7636         ProcessInfoService(ActivityManagerService activityManagerService) {
7637             mActivityManagerService = activityManagerService;
7638         }
7639
7640         @Override
7641         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7642             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7643                     /*in*/ pids, /*out*/ states, null);
7644         }
7645
7646         @Override
7647         public void getProcessStatesAndOomScoresFromPids(
7648                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7649             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7650                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7651         }
7652     }
7653
7654     /**
7655      * For each PID in the given input array, write the current process state
7656      * for that process into the states array, or -1 to indicate that no
7657      * process with the given PID exists. If scores array is provided, write
7658      * the oom score for the process into the scores array, with INVALID_ADJ
7659      * indicating the PID doesn't exist.
7660      */
7661     public void getProcessStatesAndOomScoresForPIDs(
7662             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7663         if (scores != null) {
7664             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7665                     "getProcessStatesAndOomScoresForPIDs()");
7666         }
7667
7668         if (pids == null) {
7669             throw new NullPointerException("pids");
7670         } else if (states == null) {
7671             throw new NullPointerException("states");
7672         } else if (pids.length != states.length) {
7673             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7674         } else if (scores != null && pids.length != scores.length) {
7675             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7676         }
7677
7678         synchronized (mPidsSelfLocked) {
7679             for (int i = 0; i < pids.length; i++) {
7680                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7681                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7682                         pr.curProcState;
7683                 if (scores != null) {
7684                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7685                 }
7686             }
7687         }
7688     }
7689
7690     // =========================================================
7691     // PERMISSIONS
7692     // =========================================================
7693
7694     static class PermissionController extends IPermissionController.Stub {
7695         ActivityManagerService mActivityManagerService;
7696         PermissionController(ActivityManagerService activityManagerService) {
7697             mActivityManagerService = activityManagerService;
7698         }
7699
7700         @Override
7701         public boolean checkPermission(String permission, int pid, int uid) {
7702             return mActivityManagerService.checkPermission(permission, pid,
7703                     uid) == PackageManager.PERMISSION_GRANTED;
7704         }
7705
7706         @Override
7707         public String[] getPackagesForUid(int uid) {
7708             return mActivityManagerService.mContext.getPackageManager()
7709                     .getPackagesForUid(uid);
7710         }
7711
7712         @Override
7713         public boolean isRuntimePermission(String permission) {
7714             try {
7715                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7716                         .getPermissionInfo(permission, 0);
7717                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7718             } catch (NameNotFoundException nnfe) {
7719                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7720             }
7721             return false;
7722         }
7723     }
7724
7725     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7726         @Override
7727         public int checkComponentPermission(String permission, int pid, int uid,
7728                 int owningUid, boolean exported) {
7729             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7730                     owningUid, exported);
7731         }
7732
7733         @Override
7734         public Object getAMSLock() {
7735             return ActivityManagerService.this;
7736         }
7737     }
7738
7739     /**
7740      * This can be called with or without the global lock held.
7741      */
7742     int checkComponentPermission(String permission, int pid, int uid,
7743             int owningUid, boolean exported) {
7744         if (pid == MY_PID) {
7745             return PackageManager.PERMISSION_GRANTED;
7746         }
7747         return ActivityManager.checkComponentPermission(permission, uid,
7748                 owningUid, exported);
7749     }
7750
7751     /**
7752      * As the only public entry point for permissions checking, this method
7753      * can enforce the semantic that requesting a check on a null global
7754      * permission is automatically denied.  (Internally a null permission
7755      * string is used when calling {@link #checkComponentPermission} in cases
7756      * when only uid-based security is needed.)
7757      *
7758      * This can be called with or without the global lock held.
7759      */
7760     @Override
7761     public int checkPermission(String permission, int pid, int uid) {
7762         if (permission == null) {
7763             return PackageManager.PERMISSION_DENIED;
7764         }
7765         return checkComponentPermission(permission, pid, uid, -1, true);
7766     }
7767
7768     @Override
7769     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7770         if (permission == null) {
7771             return PackageManager.PERMISSION_DENIED;
7772         }
7773
7774         // We might be performing an operation on behalf of an indirect binder
7775         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7776         // client identity accordingly before proceeding.
7777         Identity tlsIdentity = sCallerIdentity.get();
7778         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7779             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7780                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7781             uid = tlsIdentity.uid;
7782             pid = tlsIdentity.pid;
7783         }
7784
7785         return checkComponentPermission(permission, pid, uid, -1, true);
7786     }
7787
7788     /**
7789      * Binder IPC calls go through the public entry point.
7790      * This can be called with or without the global lock held.
7791      */
7792     int checkCallingPermission(String permission) {
7793         return checkPermission(permission,
7794                 Binder.getCallingPid(),
7795                 UserHandle.getAppId(Binder.getCallingUid()));
7796     }
7797
7798     /**
7799      * This can be called with or without the global lock held.
7800      */
7801     void enforceCallingPermission(String permission, String func) {
7802         if (checkCallingPermission(permission)
7803                 == PackageManager.PERMISSION_GRANTED) {
7804             return;
7805         }
7806
7807         String msg = "Permission Denial: " + func + " from pid="
7808                 + Binder.getCallingPid()
7809                 + ", uid=" + Binder.getCallingUid()
7810                 + " requires " + permission;
7811         Slog.w(TAG, msg);
7812         throw new SecurityException(msg);
7813     }
7814
7815     /**
7816      * Determine if UID is holding permissions required to access {@link Uri} in
7817      * the given {@link ProviderInfo}. Final permission checking is always done
7818      * in {@link ContentProvider}.
7819      */
7820     private final boolean checkHoldingPermissionsLocked(
7821             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7822         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7823                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7824         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7825             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7826                     != PERMISSION_GRANTED) {
7827                 return false;
7828             }
7829         }
7830         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7831     }
7832
7833     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7834             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7835         if (pi.applicationInfo.uid == uid) {
7836             return true;
7837         } else if (!pi.exported) {
7838             return false;
7839         }
7840
7841         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7842         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7843         try {
7844             // check if target holds top-level <provider> permissions
7845             if (!readMet && pi.readPermission != null && considerUidPermissions
7846                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7847                 readMet = true;
7848             }
7849             if (!writeMet && pi.writePermission != null && considerUidPermissions
7850                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7851                 writeMet = true;
7852             }
7853
7854             // track if unprotected read/write is allowed; any denied
7855             // <path-permission> below removes this ability
7856             boolean allowDefaultRead = pi.readPermission == null;
7857             boolean allowDefaultWrite = pi.writePermission == null;
7858
7859             // check if target holds any <path-permission> that match uri
7860             final PathPermission[] pps = pi.pathPermissions;
7861             if (pps != null) {
7862                 final String path = grantUri.uri.getPath();
7863                 int i = pps.length;
7864                 while (i > 0 && (!readMet || !writeMet)) {
7865                     i--;
7866                     PathPermission pp = pps[i];
7867                     if (pp.match(path)) {
7868                         if (!readMet) {
7869                             final String pprperm = pp.getReadPermission();
7870                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7871                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7872                                     + ": match=" + pp.match(path)
7873                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7874                             if (pprperm != null) {
7875                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7876                                         == PERMISSION_GRANTED) {
7877                                     readMet = true;
7878                                 } else {
7879                                     allowDefaultRead = false;
7880                                 }
7881                             }
7882                         }
7883                         if (!writeMet) {
7884                             final String ppwperm = pp.getWritePermission();
7885                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7887                                     + ": match=" + pp.match(path)
7888                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7889                             if (ppwperm != null) {
7890                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7891                                         == PERMISSION_GRANTED) {
7892                                     writeMet = true;
7893                                 } else {
7894                                     allowDefaultWrite = false;
7895                                 }
7896                             }
7897                         }
7898                     }
7899                 }
7900             }
7901
7902             // grant unprotected <provider> read/write, if not blocked by
7903             // <path-permission> above
7904             if (allowDefaultRead) readMet = true;
7905             if (allowDefaultWrite) writeMet = true;
7906
7907         } catch (RemoteException e) {
7908             return false;
7909         }
7910
7911         return readMet && writeMet;
7912     }
7913
7914     public int getAppStartMode(int uid, String packageName) {
7915         synchronized (this) {
7916             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7917         }
7918     }
7919
7920     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7921             boolean allowWhenForeground) {
7922         UidRecord uidRec = mActiveUids.get(uid);
7923         if (!mLenientBackgroundCheck) {
7924             if (!allowWhenForeground || uidRec == null
7925                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7926                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7927                         packageName) != AppOpsManager.MODE_ALLOWED) {
7928                     return ActivityManager.APP_START_MODE_DELAYED;
7929                 }
7930             }
7931
7932         } else if (uidRec == null || uidRec.idle) {
7933             if (callingPid >= 0) {
7934                 ProcessRecord proc;
7935                 synchronized (mPidsSelfLocked) {
7936                     proc = mPidsSelfLocked.get(callingPid);
7937                 }
7938                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7939                     // Whoever is instigating this is in the foreground, so we will allow it
7940                     // to go through.
7941                     return ActivityManager.APP_START_MODE_NORMAL;
7942                 }
7943             }
7944             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7945                     != AppOpsManager.MODE_ALLOWED) {
7946                 return ActivityManager.APP_START_MODE_DELAYED;
7947             }
7948         }
7949         return ActivityManager.APP_START_MODE_NORMAL;
7950     }
7951
7952     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7953         ProviderInfo pi = null;
7954         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7955         if (cpr != null) {
7956             pi = cpr.info;
7957         } else {
7958             try {
7959                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7960                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7961                         userHandle);
7962             } catch (RemoteException ex) {
7963             }
7964         }
7965         return pi;
7966     }
7967
7968     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7969         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7970         if (targetUris != null) {
7971             return targetUris.get(grantUri);
7972         }
7973         return null;
7974     }
7975
7976     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7977             String targetPkg, int targetUid, GrantUri grantUri) {
7978         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7979         if (targetUris == null) {
7980             targetUris = Maps.newArrayMap();
7981             mGrantedUriPermissions.put(targetUid, targetUris);
7982         }
7983
7984         UriPermission perm = targetUris.get(grantUri);
7985         if (perm == null) {
7986             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7987             targetUris.put(grantUri, perm);
7988         }
7989
7990         return perm;
7991     }
7992
7993     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7994             final int modeFlags) {
7995         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7996         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7997                 : UriPermission.STRENGTH_OWNED;
7998
7999         // Root gets to do everything.
8000         if (uid == 0) {
8001             return true;
8002         }
8003
8004         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8005         if (perms == null) return false;
8006
8007         // First look for exact match
8008         final UriPermission exactPerm = perms.get(grantUri);
8009         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8010             return true;
8011         }
8012
8013         // No exact match, look for prefixes
8014         final int N = perms.size();
8015         for (int i = 0; i < N; i++) {
8016             final UriPermission perm = perms.valueAt(i);
8017             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8018                     && perm.getStrength(modeFlags) >= minStrength) {
8019                 return true;
8020             }
8021         }
8022
8023         return false;
8024     }
8025
8026     /**
8027      * @param uri This uri must NOT contain an embedded userId.
8028      * @param userId The userId in which the uri is to be resolved.
8029      */
8030     @Override
8031     public int checkUriPermission(Uri uri, int pid, int uid,
8032             final int modeFlags, int userId, IBinder callerToken) {
8033         enforceNotIsolatedCaller("checkUriPermission");
8034
8035         // Another redirected-binder-call permissions check as in
8036         // {@link checkPermissionWithToken}.
8037         Identity tlsIdentity = sCallerIdentity.get();
8038         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8039             uid = tlsIdentity.uid;
8040             pid = tlsIdentity.pid;
8041         }
8042
8043         // Our own process gets to do everything.
8044         if (pid == MY_PID) {
8045             return PackageManager.PERMISSION_GRANTED;
8046         }
8047         synchronized (this) {
8048             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8049                     ? PackageManager.PERMISSION_GRANTED
8050                     : PackageManager.PERMISSION_DENIED;
8051         }
8052     }
8053
8054     /**
8055      * Check if the targetPkg can be granted permission to access uri by
8056      * the callingUid using the given modeFlags.  Throws a security exception
8057      * if callingUid is not allowed to do this.  Returns the uid of the target
8058      * if the URI permission grant should be performed; returns -1 if it is not
8059      * needed (for example targetPkg already has permission to access the URI).
8060      * If you already know the uid of the target, you can supply it in
8061      * lastTargetUid else set that to -1.
8062      */
8063     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8064             final int modeFlags, int lastTargetUid) {
8065         if (!Intent.isAccessUriMode(modeFlags)) {
8066             return -1;
8067         }
8068
8069         if (targetPkg != null) {
8070             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8071                     "Checking grant " + targetPkg + " permission to " + grantUri);
8072         }
8073
8074         final IPackageManager pm = AppGlobals.getPackageManager();
8075
8076         // If this is not a content: uri, we can't do anything with it.
8077         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8078             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                     "Can't grant URI permission for non-content URI: " + grantUri);
8080             return -1;
8081         }
8082
8083         final String authority = grantUri.uri.getAuthority();
8084         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8085                 MATCH_DEBUG_TRIAGED_MISSING);
8086         if (pi == null) {
8087             Slog.w(TAG, "No content provider found for permission check: " +
8088                     grantUri.uri.toSafeString());
8089             return -1;
8090         }
8091
8092         int targetUid = lastTargetUid;
8093         if (targetUid < 0 && targetPkg != null) {
8094             try {
8095                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8096                         UserHandle.getUserId(callingUid));
8097                 if (targetUid < 0) {
8098                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                             "Can't grant URI permission no uid for: " + targetPkg);
8100                     return -1;
8101                 }
8102             } catch (RemoteException ex) {
8103                 return -1;
8104             }
8105         }
8106
8107         if (targetUid >= 0) {
8108             // First...  does the target actually need this permission?
8109             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8110                 // No need to grant the target this permission.
8111                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112                         "Target " + targetPkg + " already has full permission to " + grantUri);
8113                 return -1;
8114             }
8115         } else {
8116             // First...  there is no target package, so can anyone access it?
8117             boolean allowed = pi.exported;
8118             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8119                 if (pi.readPermission != null) {
8120                     allowed = false;
8121                 }
8122             }
8123             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8124                 if (pi.writePermission != null) {
8125                     allowed = false;
8126                 }
8127             }
8128             if (allowed) {
8129                 return -1;
8130             }
8131         }
8132
8133         /* There is a special cross user grant if:
8134          * - The target is on another user.
8135          * - Apps on the current user can access the uri without any uid permissions.
8136          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8137          * grant uri permissions.
8138          */
8139         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8140                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8141                 modeFlags, false /*without considering the uid permissions*/);
8142
8143         // Second...  is the provider allowing granting of URI permissions?
8144         if (!specialCrossUserGrant) {
8145             if (!pi.grantUriPermissions) {
8146                 throw new SecurityException("Provider " + pi.packageName
8147                         + "/" + pi.name
8148                         + " does not allow granting of Uri permissions (uri "
8149                         + grantUri + ")");
8150             }
8151             if (pi.uriPermissionPatterns != null) {
8152                 final int N = pi.uriPermissionPatterns.length;
8153                 boolean allowed = false;
8154                 for (int i=0; i<N; i++) {
8155                     if (pi.uriPermissionPatterns[i] != null
8156                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8157                         allowed = true;
8158                         break;
8159                     }
8160                 }
8161                 if (!allowed) {
8162                     throw new SecurityException("Provider " + pi.packageName
8163                             + "/" + pi.name
8164                             + " does not allow granting of permission to path of Uri "
8165                             + grantUri);
8166                 }
8167             }
8168         }
8169
8170         // Third...  does the caller itself have permission to access
8171         // this uri?
8172         final int callingAppId = UserHandle.getAppId(callingUid);
8173         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8174             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8175                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8176             return -1;
8177         } else {
8178             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8179                 // Require they hold a strong enough Uri permission
8180                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8181                     throw new SecurityException("Uid " + callingUid
8182                             + " does not have permission to uri " + grantUri);
8183                 }
8184             }
8185         }
8186         return targetUid;
8187     }
8188
8189     /**
8190      * @param uri This uri must NOT contain an embedded userId.
8191      * @param userId The userId in which the uri is to be resolved.
8192      */
8193     @Override
8194     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8195             final int modeFlags, int userId) {
8196         enforceNotIsolatedCaller("checkGrantUriPermission");
8197         synchronized(this) {
8198             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8199                     new GrantUri(userId, uri, false), modeFlags, -1);
8200         }
8201     }
8202
8203     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8204             final int modeFlags, UriPermissionOwner owner) {
8205         if (!Intent.isAccessUriMode(modeFlags)) {
8206             return;
8207         }
8208
8209         // So here we are: the caller has the assumed permission
8210         // to the uri, and the target doesn't.  Let's now give this to
8211         // the target.
8212
8213         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8214                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8215
8216         final String authority = grantUri.uri.getAuthority();
8217         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8218                 MATCH_DEBUG_TRIAGED_MISSING);
8219         if (pi == null) {
8220             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8221             return;
8222         }
8223
8224         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8225             grantUri.prefix = true;
8226         }
8227         final UriPermission perm = findOrCreateUriPermissionLocked(
8228                 pi.packageName, targetPkg, targetUid, grantUri);
8229         perm.grantModes(modeFlags, owner);
8230     }
8231
8232     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8233             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8234         if (targetPkg == null) {
8235             throw new NullPointerException("targetPkg");
8236         }
8237         int targetUid;
8238         final IPackageManager pm = AppGlobals.getPackageManager();
8239         try {
8240             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8241         } catch (RemoteException ex) {
8242             return;
8243         }
8244
8245         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8246                 targetUid);
8247         if (targetUid < 0) {
8248             return;
8249         }
8250
8251         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8252                 owner);
8253     }
8254
8255     static class NeededUriGrants extends ArrayList<GrantUri> {
8256         final String targetPkg;
8257         final int targetUid;
8258         final int flags;
8259
8260         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8261             this.targetPkg = targetPkg;
8262             this.targetUid = targetUid;
8263             this.flags = flags;
8264         }
8265     }
8266
8267     /**
8268      * Like checkGrantUriPermissionLocked, but takes an Intent.
8269      */
8270     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8271             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8272         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8273                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8274                 + " clip=" + (intent != null ? intent.getClipData() : null)
8275                 + " from " + intent + "; flags=0x"
8276                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8277
8278         if (targetPkg == null) {
8279             throw new NullPointerException("targetPkg");
8280         }
8281
8282         if (intent == null) {
8283             return null;
8284         }
8285         Uri data = intent.getData();
8286         ClipData clip = intent.getClipData();
8287         if (data == null && clip == null) {
8288             return null;
8289         }
8290         // Default userId for uris in the intent (if they don't specify it themselves)
8291         int contentUserHint = intent.getContentUserHint();
8292         if (contentUserHint == UserHandle.USER_CURRENT) {
8293             contentUserHint = UserHandle.getUserId(callingUid);
8294         }
8295         final IPackageManager pm = AppGlobals.getPackageManager();
8296         int targetUid;
8297         if (needed != null) {
8298             targetUid = needed.targetUid;
8299         } else {
8300             try {
8301                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8302                         targetUserId);
8303             } catch (RemoteException ex) {
8304                 return null;
8305             }
8306             if (targetUid < 0) {
8307                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8308                         "Can't grant URI permission no uid for: " + targetPkg
8309                         + " on user " + targetUserId);
8310                 return null;
8311             }
8312         }
8313         if (data != null) {
8314             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8315             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8316                     targetUid);
8317             if (targetUid > 0) {
8318                 if (needed == null) {
8319                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8320                 }
8321                 needed.add(grantUri);
8322             }
8323         }
8324         if (clip != null) {
8325             for (int i=0; i<clip.getItemCount(); i++) {
8326                 Uri uri = clip.getItemAt(i).getUri();
8327                 if (uri != null) {
8328                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8329                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8330                             targetUid);
8331                     if (targetUid > 0) {
8332                         if (needed == null) {
8333                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8334                         }
8335                         needed.add(grantUri);
8336                     }
8337                 } else {
8338                     Intent clipIntent = clip.getItemAt(i).getIntent();
8339                     if (clipIntent != null) {
8340                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8341                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8342                         if (newNeeded != null) {
8343                             needed = newNeeded;
8344                         }
8345                     }
8346                 }
8347             }
8348         }
8349
8350         return needed;
8351     }
8352
8353     /**
8354      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8355      */
8356     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8357             UriPermissionOwner owner) {
8358         if (needed != null) {
8359             for (int i=0; i<needed.size(); i++) {
8360                 GrantUri grantUri = needed.get(i);
8361                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8362                         grantUri, needed.flags, owner);
8363             }
8364         }
8365     }
8366
8367     void grantUriPermissionFromIntentLocked(int callingUid,
8368             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8369         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8370                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8371         if (needed == null) {
8372             return;
8373         }
8374
8375         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8376     }
8377
8378     /**
8379      * @param uri This uri must NOT contain an embedded userId.
8380      * @param userId The userId in which the uri is to be resolved.
8381      */
8382     @Override
8383     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8384             final int modeFlags, int userId) {
8385         enforceNotIsolatedCaller("grantUriPermission");
8386         GrantUri grantUri = new GrantUri(userId, uri, false);
8387         synchronized(this) {
8388             final ProcessRecord r = getRecordForAppLocked(caller);
8389             if (r == null) {
8390                 throw new SecurityException("Unable to find app for caller "
8391                         + caller
8392                         + " when granting permission to uri " + grantUri);
8393             }
8394             if (targetPkg == null) {
8395                 throw new IllegalArgumentException("null target");
8396             }
8397             if (grantUri == null) {
8398                 throw new IllegalArgumentException("null uri");
8399             }
8400
8401             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8402                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8403                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8404                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8405
8406             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8407                     UserHandle.getUserId(r.uid));
8408         }
8409     }
8410
8411     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8412         if (perm.modeFlags == 0) {
8413             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8414                     perm.targetUid);
8415             if (perms != null) {
8416                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8417                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8418
8419                 perms.remove(perm.uri);
8420                 if (perms.isEmpty()) {
8421                     mGrantedUriPermissions.remove(perm.targetUid);
8422                 }
8423             }
8424         }
8425     }
8426
8427     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8428         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429                 "Revoking all granted permissions to " + grantUri);
8430
8431         final IPackageManager pm = AppGlobals.getPackageManager();
8432         final String authority = grantUri.uri.getAuthority();
8433         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8434                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8435         if (pi == null) {
8436             Slog.w(TAG, "No content provider found for permission revoke: "
8437                     + grantUri.toSafeString());
8438             return;
8439         }
8440
8441         // Does the caller have this permission on the URI?
8442         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8443             // If they don't have direct access to the URI, then revoke any
8444             // ownerless URI permissions that have been granted to them.
8445             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8446             if (perms != null) {
8447                 boolean persistChanged = false;
8448                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8449                     final UriPermission perm = it.next();
8450                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8451                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8452                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8453                                 "Revoking non-owned " + perm.targetUid
8454                                 + " permission to " + perm.uri);
8455                         persistChanged |= perm.revokeModes(
8456                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8457                         if (perm.modeFlags == 0) {
8458                             it.remove();
8459                         }
8460                     }
8461                 }
8462                 if (perms.isEmpty()) {
8463                     mGrantedUriPermissions.remove(callingUid);
8464                 }
8465                 if (persistChanged) {
8466                     schedulePersistUriGrants();
8467                 }
8468             }
8469             return;
8470         }
8471
8472         boolean persistChanged = false;
8473
8474         // Go through all of the permissions and remove any that match.
8475         int N = mGrantedUriPermissions.size();
8476         for (int i = 0; i < N; i++) {
8477             final int targetUid = mGrantedUriPermissions.keyAt(i);
8478             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8479
8480             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8481                 final UriPermission perm = it.next();
8482                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8483                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8484                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8485                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8486                     persistChanged |= perm.revokeModes(
8487                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8488                     if (perm.modeFlags == 0) {
8489                         it.remove();
8490                     }
8491                 }
8492             }
8493
8494             if (perms.isEmpty()) {
8495                 mGrantedUriPermissions.remove(targetUid);
8496                 N--;
8497                 i--;
8498             }
8499         }
8500
8501         if (persistChanged) {
8502             schedulePersistUriGrants();
8503         }
8504     }
8505
8506     /**
8507      * @param uri This uri must NOT contain an embedded userId.
8508      * @param userId The userId in which the uri is to be resolved.
8509      */
8510     @Override
8511     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8512             int userId) {
8513         enforceNotIsolatedCaller("revokeUriPermission");
8514         synchronized(this) {
8515             final ProcessRecord r = getRecordForAppLocked(caller);
8516             if (r == null) {
8517                 throw new SecurityException("Unable to find app for caller "
8518                         + caller
8519                         + " when revoking permission to uri " + uri);
8520             }
8521             if (uri == null) {
8522                 Slog.w(TAG, "revokeUriPermission: null uri");
8523                 return;
8524             }
8525
8526             if (!Intent.isAccessUriMode(modeFlags)) {
8527                 return;
8528             }
8529
8530             final String authority = uri.getAuthority();
8531             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8532                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8533             if (pi == null) {
8534                 Slog.w(TAG, "No content provider found for permission revoke: "
8535                         + uri.toSafeString());
8536                 return;
8537             }
8538
8539             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8540         }
8541     }
8542
8543     /**
8544      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8545      * given package.
8546      *
8547      * @param packageName Package name to match, or {@code null} to apply to all
8548      *            packages.
8549      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8550      *            to all users.
8551      * @param persistable If persistable grants should be removed.
8552      */
8553     private void removeUriPermissionsForPackageLocked(
8554             String packageName, int userHandle, boolean persistable) {
8555         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8556             throw new IllegalArgumentException("Must narrow by either package or user");
8557         }
8558
8559         boolean persistChanged = false;
8560
8561         int N = mGrantedUriPermissions.size();
8562         for (int i = 0; i < N; i++) {
8563             final int targetUid = mGrantedUriPermissions.keyAt(i);
8564             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8565
8566             // Only inspect grants matching user
8567             if (userHandle == UserHandle.USER_ALL
8568                     || userHandle == UserHandle.getUserId(targetUid)) {
8569                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8570                     final UriPermission perm = it.next();
8571
8572                     // Only inspect grants matching package
8573                     if (packageName == null || perm.sourcePkg.equals(packageName)
8574                             || perm.targetPkg.equals(packageName)) {
8575                         // Hacky solution as part of fixing a security bug; ignore
8576                         // grants associated with DownloadManager so we don't have
8577                         // to immediately launch it to regrant the permissions
8578                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8579                                 && !persistable) continue;
8580
8581                         persistChanged |= perm.revokeModes(persistable
8582                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8583
8584                         // Only remove when no modes remain; any persisted grants
8585                         // will keep this alive.
8586                         if (perm.modeFlags == 0) {
8587                             it.remove();
8588                         }
8589                     }
8590                 }
8591
8592                 if (perms.isEmpty()) {
8593                     mGrantedUriPermissions.remove(targetUid);
8594                     N--;
8595                     i--;
8596                 }
8597             }
8598         }
8599
8600         if (persistChanged) {
8601             schedulePersistUriGrants();
8602         }
8603     }
8604
8605     @Override
8606     public IBinder newUriPermissionOwner(String name) {
8607         enforceNotIsolatedCaller("newUriPermissionOwner");
8608         synchronized(this) {
8609             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8610             return owner.getExternalTokenLocked();
8611         }
8612     }
8613
8614     @Override
8615     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8616         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8617         synchronized(this) {
8618             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8619             if (r == null) {
8620                 throw new IllegalArgumentException("Activity does not exist; token="
8621                         + activityToken);
8622             }
8623             return r.getUriPermissionsLocked().getExternalTokenLocked();
8624         }
8625     }
8626     /**
8627      * @param uri This uri must NOT contain an embedded userId.
8628      * @param sourceUserId The userId in which the uri is to be resolved.
8629      * @param targetUserId The userId of the app that receives the grant.
8630      */
8631     @Override
8632     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8633             final int modeFlags, int sourceUserId, int targetUserId) {
8634         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8635                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8636                 "grantUriPermissionFromOwner", null);
8637         synchronized(this) {
8638             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8639             if (owner == null) {
8640                 throw new IllegalArgumentException("Unknown owner: " + token);
8641             }
8642             if (fromUid != Binder.getCallingUid()) {
8643                 if (Binder.getCallingUid() != Process.myUid()) {
8644                     // Only system code can grant URI permissions on behalf
8645                     // of other users.
8646                     throw new SecurityException("nice try");
8647                 }
8648             }
8649             if (targetPkg == null) {
8650                 throw new IllegalArgumentException("null target");
8651             }
8652             if (uri == null) {
8653                 throw new IllegalArgumentException("null uri");
8654             }
8655
8656             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8657                     modeFlags, owner, targetUserId);
8658         }
8659     }
8660
8661     /**
8662      * @param uri This uri must NOT contain an embedded userId.
8663      * @param userId The userId in which the uri is to be resolved.
8664      */
8665     @Override
8666     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8667         synchronized(this) {
8668             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8669             if (owner == null) {
8670                 throw new IllegalArgumentException("Unknown owner: " + token);
8671             }
8672
8673             if (uri == null) {
8674                 owner.removeUriPermissionsLocked(mode);
8675             } else {
8676                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8677                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8678             }
8679         }
8680     }
8681
8682     private void schedulePersistUriGrants() {
8683         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8684             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8685                     10 * DateUtils.SECOND_IN_MILLIS);
8686         }
8687     }
8688
8689     private void writeGrantedUriPermissions() {
8690         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8691
8692         // Snapshot permissions so we can persist without lock
8693         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8694         synchronized (this) {
8695             final int size = mGrantedUriPermissions.size();
8696             for (int i = 0; i < size; i++) {
8697                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8698                 for (UriPermission perm : perms.values()) {
8699                     if (perm.persistedModeFlags != 0) {
8700                         persist.add(perm.snapshot());
8701                     }
8702                 }
8703             }
8704         }
8705
8706         FileOutputStream fos = null;
8707         try {
8708             fos = mGrantFile.startWrite();
8709
8710             XmlSerializer out = new FastXmlSerializer();
8711             out.setOutput(fos, StandardCharsets.UTF_8.name());
8712             out.startDocument(null, true);
8713             out.startTag(null, TAG_URI_GRANTS);
8714             for (UriPermission.Snapshot perm : persist) {
8715                 out.startTag(null, TAG_URI_GRANT);
8716                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8717                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8718                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8719                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8720                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8721                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8722                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8723                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8724                 out.endTag(null, TAG_URI_GRANT);
8725             }
8726             out.endTag(null, TAG_URI_GRANTS);
8727             out.endDocument();
8728
8729             mGrantFile.finishWrite(fos);
8730         } catch (IOException e) {
8731             if (fos != null) {
8732                 mGrantFile.failWrite(fos);
8733             }
8734         }
8735     }
8736
8737     private void readGrantedUriPermissionsLocked() {
8738         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8739
8740         final long now = System.currentTimeMillis();
8741
8742         FileInputStream fis = null;
8743         try {
8744             fis = mGrantFile.openRead();
8745             final XmlPullParser in = Xml.newPullParser();
8746             in.setInput(fis, StandardCharsets.UTF_8.name());
8747
8748             int type;
8749             while ((type = in.next()) != END_DOCUMENT) {
8750                 final String tag = in.getName();
8751                 if (type == START_TAG) {
8752                     if (TAG_URI_GRANT.equals(tag)) {
8753                         final int sourceUserId;
8754                         final int targetUserId;
8755                         final int userHandle = readIntAttribute(in,
8756                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8757                         if (userHandle != UserHandle.USER_NULL) {
8758                             // For backwards compatibility.
8759                             sourceUserId = userHandle;
8760                             targetUserId = userHandle;
8761                         } else {
8762                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8763                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8764                         }
8765                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8766                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8767                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8768                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8769                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8770                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8771
8772                         // Sanity check that provider still belongs to source package
8773                         // Both direct boot aware and unaware packages are fine as we
8774                         // will do filtering at query time to avoid multiple parsing.
8775                         final ProviderInfo pi = getProviderInfoLocked(
8776                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8777                                         | MATCH_DIRECT_BOOT_UNAWARE);
8778                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8779                             int targetUid = -1;
8780                             try {
8781                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8782                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8783                             } catch (RemoteException e) {
8784                             }
8785                             if (targetUid != -1) {
8786                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8787                                         sourcePkg, targetPkg, targetUid,
8788                                         new GrantUri(sourceUserId, uri, prefix));
8789                                 perm.initPersistedModes(modeFlags, createdTime);
8790                             }
8791                         } else {
8792                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8793                                     + " but instead found " + pi);
8794                         }
8795                     }
8796                 }
8797             }
8798         } catch (FileNotFoundException e) {
8799             // Missing grants is okay
8800         } catch (IOException e) {
8801             Slog.wtf(TAG, "Failed reading Uri grants", e);
8802         } catch (XmlPullParserException e) {
8803             Slog.wtf(TAG, "Failed reading Uri grants", e);
8804         } finally {
8805             IoUtils.closeQuietly(fis);
8806         }
8807     }
8808
8809     /**
8810      * @param uri This uri must NOT contain an embedded userId.
8811      * @param userId The userId in which the uri is to be resolved.
8812      */
8813     @Override
8814     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8815         enforceNotIsolatedCaller("takePersistableUriPermission");
8816
8817         Preconditions.checkFlagsArgument(modeFlags,
8818                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8819
8820         synchronized (this) {
8821             final int callingUid = Binder.getCallingUid();
8822             boolean persistChanged = false;
8823             GrantUri grantUri = new GrantUri(userId, uri, false);
8824
8825             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8826                     new GrantUri(userId, uri, false));
8827             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8828                     new GrantUri(userId, uri, true));
8829
8830             final boolean exactValid = (exactPerm != null)
8831                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8832             final boolean prefixValid = (prefixPerm != null)
8833                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8834
8835             if (!(exactValid || prefixValid)) {
8836                 throw new SecurityException("No persistable permission grants found for UID "
8837                         + callingUid + " and Uri " + grantUri.toSafeString());
8838             }
8839
8840             if (exactValid) {
8841                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8842             }
8843             if (prefixValid) {
8844                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8845             }
8846
8847             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8848
8849             if (persistChanged) {
8850                 schedulePersistUriGrants();
8851             }
8852         }
8853     }
8854
8855     /**
8856      * @param uri This uri must NOT contain an embedded userId.
8857      * @param userId The userId in which the uri is to be resolved.
8858      */
8859     @Override
8860     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8861         enforceNotIsolatedCaller("releasePersistableUriPermission");
8862
8863         Preconditions.checkFlagsArgument(modeFlags,
8864                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8865
8866         synchronized (this) {
8867             final int callingUid = Binder.getCallingUid();
8868             boolean persistChanged = false;
8869
8870             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8871                     new GrantUri(userId, uri, false));
8872             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8873                     new GrantUri(userId, uri, true));
8874             if (exactPerm == null && prefixPerm == null) {
8875                 throw new SecurityException("No permission grants found for UID " + callingUid
8876                         + " and Uri " + uri.toSafeString());
8877             }
8878
8879             if (exactPerm != null) {
8880                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8881                 removeUriPermissionIfNeededLocked(exactPerm);
8882             }
8883             if (prefixPerm != null) {
8884                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8885                 removeUriPermissionIfNeededLocked(prefixPerm);
8886             }
8887
8888             if (persistChanged) {
8889                 schedulePersistUriGrants();
8890             }
8891         }
8892     }
8893
8894     /**
8895      * Prune any older {@link UriPermission} for the given UID until outstanding
8896      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8897      *
8898      * @return if any mutations occured that require persisting.
8899      */
8900     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8901         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8902         if (perms == null) return false;
8903         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8904
8905         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8906         for (UriPermission perm : perms.values()) {
8907             if (perm.persistedModeFlags != 0) {
8908                 persisted.add(perm);
8909             }
8910         }
8911
8912         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8913         if (trimCount <= 0) return false;
8914
8915         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8916         for (int i = 0; i < trimCount; i++) {
8917             final UriPermission perm = persisted.get(i);
8918
8919             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8920                     "Trimming grant created at " + perm.persistedCreateTime);
8921
8922             perm.releasePersistableModes(~0);
8923             removeUriPermissionIfNeededLocked(perm);
8924         }
8925
8926         return true;
8927     }
8928
8929     @Override
8930     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8931             String packageName, boolean incoming) {
8932         enforceNotIsolatedCaller("getPersistedUriPermissions");
8933         Preconditions.checkNotNull(packageName, "packageName");
8934
8935         final int callingUid = Binder.getCallingUid();
8936         final int callingUserId = UserHandle.getUserId(callingUid);
8937         final IPackageManager pm = AppGlobals.getPackageManager();
8938         try {
8939             final int packageUid = pm.getPackageUid(packageName,
8940                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8941             if (packageUid != callingUid) {
8942                 throw new SecurityException(
8943                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8944             }
8945         } catch (RemoteException e) {
8946             throw new SecurityException("Failed to verify package name ownership");
8947         }
8948
8949         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8950         synchronized (this) {
8951             if (incoming) {
8952                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8953                         callingUid);
8954                 if (perms == null) {
8955                     Slog.w(TAG, "No permission grants found for " + packageName);
8956                 } else {
8957                     for (UriPermission perm : perms.values()) {
8958                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8959                             result.add(perm.buildPersistedPublicApiObject());
8960                         }
8961                     }
8962                 }
8963             } else {
8964                 final int size = mGrantedUriPermissions.size();
8965                 for (int i = 0; i < size; i++) {
8966                     final ArrayMap<GrantUri, UriPermission> perms =
8967                             mGrantedUriPermissions.valueAt(i);
8968                     for (UriPermission perm : perms.values()) {
8969                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8970                             result.add(perm.buildPersistedPublicApiObject());
8971                         }
8972                     }
8973                 }
8974             }
8975         }
8976         return new ParceledListSlice<android.content.UriPermission>(result);
8977     }
8978
8979     @Override
8980     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8981             String packageName, int userId) {
8982         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8983                 "getGrantedUriPermissions");
8984
8985         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8986         synchronized (this) {
8987             final int size = mGrantedUriPermissions.size();
8988             for (int i = 0; i < size; i++) {
8989                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8990                 for (UriPermission perm : perms.values()) {
8991                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8992                             && perm.persistedModeFlags != 0) {
8993                         result.add(perm.buildPersistedPublicApiObject());
8994                     }
8995                 }
8996             }
8997         }
8998         return new ParceledListSlice<android.content.UriPermission>(result);
8999     }
9000
9001     @Override
9002     public void clearGrantedUriPermissions(String packageName, int userId) {
9003         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9004                 "clearGrantedUriPermissions");
9005         removeUriPermissionsForPackageLocked(packageName, userId, true);
9006     }
9007
9008     @Override
9009     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9010         synchronized (this) {
9011             ProcessRecord app =
9012                 who != null ? getRecordForAppLocked(who) : null;
9013             if (app == null) return;
9014
9015             Message msg = Message.obtain();
9016             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9017             msg.obj = app;
9018             msg.arg1 = waiting ? 1 : 0;
9019             mUiHandler.sendMessage(msg);
9020         }
9021     }
9022
9023     @Override
9024     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9025         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9026         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9027         outInfo.availMem = Process.getFreeMemory();
9028         outInfo.totalMem = Process.getTotalMemory();
9029         outInfo.threshold = homeAppMem;
9030         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9031         outInfo.hiddenAppThreshold = cachedAppMem;
9032         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9033                 ProcessList.SERVICE_ADJ);
9034         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9035                 ProcessList.VISIBLE_APP_ADJ);
9036         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9037                 ProcessList.FOREGROUND_APP_ADJ);
9038     }
9039
9040     // =========================================================
9041     // TASK MANAGEMENT
9042     // =========================================================
9043
9044     @Override
9045     public List<IAppTask> getAppTasks(String callingPackage) {
9046         int callingUid = Binder.getCallingUid();
9047         long ident = Binder.clearCallingIdentity();
9048
9049         synchronized(this) {
9050             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9051             try {
9052                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9053
9054                 final int N = mRecentTasks.size();
9055                 for (int i = 0; i < N; i++) {
9056                     TaskRecord tr = mRecentTasks.get(i);
9057                     // Skip tasks that do not match the caller.  We don't need to verify
9058                     // callingPackage, because we are also limiting to callingUid and know
9059                     // that will limit to the correct security sandbox.
9060                     if (tr.effectiveUid != callingUid) {
9061                         continue;
9062                     }
9063                     Intent intent = tr.getBaseIntent();
9064                     if (intent == null ||
9065                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9066                         continue;
9067                     }
9068                     ActivityManager.RecentTaskInfo taskInfo =
9069                             createRecentTaskInfoFromTaskRecord(tr);
9070                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9071                     list.add(taskImpl);
9072                 }
9073             } finally {
9074                 Binder.restoreCallingIdentity(ident);
9075             }
9076             return list;
9077         }
9078     }
9079
9080     @Override
9081     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9082         final int callingUid = Binder.getCallingUid();
9083         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9084
9085         synchronized(this) {
9086             if (DEBUG_ALL) Slog.v(
9087                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9088
9089             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9090                     callingUid);
9091
9092             // TODO: Improve with MRU list from all ActivityStacks.
9093             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9094         }
9095
9096         return list;
9097     }
9098
9099     /**
9100      * Creates a new RecentTaskInfo from a TaskRecord.
9101      */
9102     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9103         // Update the task description to reflect any changes in the task stack
9104         tr.updateTaskDescription();
9105
9106         // Compose the recent task info
9107         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9108         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9109         rti.persistentId = tr.taskId;
9110         rti.baseIntent = new Intent(tr.getBaseIntent());
9111         rti.origActivity = tr.origActivity;
9112         rti.realActivity = tr.realActivity;
9113         rti.description = tr.lastDescription;
9114         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9115         rti.userId = tr.userId;
9116         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9117         rti.firstActiveTime = tr.firstActiveTime;
9118         rti.lastActiveTime = tr.lastActiveTime;
9119         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9120         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9121         rti.numActivities = 0;
9122         if (tr.mBounds != null) {
9123             rti.bounds = new Rect(tr.mBounds);
9124         }
9125         rti.isDockable = tr.canGoInDockedStack();
9126         rti.resizeMode = tr.mResizeMode;
9127
9128         ActivityRecord base = null;
9129         ActivityRecord top = null;
9130         ActivityRecord tmp;
9131
9132         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9133             tmp = tr.mActivities.get(i);
9134             if (tmp.finishing) {
9135                 continue;
9136             }
9137             base = tmp;
9138             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9139                 top = base;
9140             }
9141             rti.numActivities++;
9142         }
9143
9144         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9145         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9146
9147         return rti;
9148     }
9149
9150     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9151         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9152                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9153         if (!allowed) {
9154             if (checkPermission(android.Manifest.permission.GET_TASKS,
9155                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9156                 // Temporary compatibility: some existing apps on the system image may
9157                 // still be requesting the old permission and not switched to the new
9158                 // one; if so, we'll still allow them full access.  This means we need
9159                 // to see if they are holding the old permission and are a system app.
9160                 try {
9161                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9162                         allowed = true;
9163                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9164                                 + " is using old GET_TASKS but privileged; allowing");
9165                     }
9166                 } catch (RemoteException e) {
9167                 }
9168             }
9169         }
9170         if (!allowed) {
9171             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9172                     + " does not hold REAL_GET_TASKS; limiting output");
9173         }
9174         return allowed;
9175     }
9176
9177     @Override
9178     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9179             int userId) {
9180         final int callingUid = Binder.getCallingUid();
9181         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9182                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9183
9184         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9185         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9186         synchronized (this) {
9187             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9188                     callingUid);
9189             final boolean detailed = checkCallingPermission(
9190                     android.Manifest.permission.GET_DETAILED_TASKS)
9191                     == PackageManager.PERMISSION_GRANTED;
9192
9193             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9194                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9195                 return ParceledListSlice.emptyList();
9196             }
9197             mRecentTasks.loadUserRecentsLocked(userId);
9198
9199             final int recentsCount = mRecentTasks.size();
9200             ArrayList<ActivityManager.RecentTaskInfo> res =
9201                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9202
9203             final Set<Integer> includedUsers;
9204             if (includeProfiles) {
9205                 includedUsers = mUserController.getProfileIds(userId);
9206             } else {
9207                 includedUsers = new HashSet<>();
9208             }
9209             includedUsers.add(Integer.valueOf(userId));
9210
9211             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9212                 TaskRecord tr = mRecentTasks.get(i);
9213                 // Only add calling user or related users recent tasks
9214                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9215                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9216                     continue;
9217                 }
9218
9219                 if (tr.realActivitySuspended) {
9220                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9221                     continue;
9222                 }
9223
9224                 // Return the entry if desired by the caller.  We always return
9225                 // the first entry, because callers always expect this to be the
9226                 // foreground app.  We may filter others if the caller has
9227                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9228                 // we should exclude the entry.
9229
9230                 if (i == 0
9231                         || withExcluded
9232                         || (tr.intent == null)
9233                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9234                                 == 0)) {
9235                     if (!allowed) {
9236                         // If the caller doesn't have the GET_TASKS permission, then only
9237                         // allow them to see a small subset of tasks -- their own and home.
9238                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9239                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9240                             continue;
9241                         }
9242                     }
9243                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9244                         if (tr.stack != null && tr.stack.isHomeStack()) {
9245                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9246                                     "Skipping, home stack task: " + tr);
9247                             continue;
9248                         }
9249                     }
9250                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9251                         final ActivityStack stack = tr.stack;
9252                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9253                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9254                                     "Skipping, top task in docked stack: " + tr);
9255                             continue;
9256                         }
9257                     }
9258                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9259                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9260                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9261                                     "Skipping, pinned stack task: " + tr);
9262                             continue;
9263                         }
9264                     }
9265                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9266                         // Don't include auto remove tasks that are finished or finishing.
9267                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9268                                 "Skipping, auto-remove without activity: " + tr);
9269                         continue;
9270                     }
9271                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9272                             && !tr.isAvailable) {
9273                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9274                                 "Skipping, unavail real act: " + tr);
9275                         continue;
9276                     }
9277
9278                     if (!tr.mUserSetupComplete) {
9279                         // Don't include task launched while user is not done setting-up.
9280                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9281                                 "Skipping, user setup not complete: " + tr);
9282                         continue;
9283                     }
9284
9285                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9286                     if (!detailed) {
9287                         rti.baseIntent.replaceExtras((Bundle)null);
9288                     }
9289
9290                     res.add(rti);
9291                     maxNum--;
9292                 }
9293             }
9294             return new ParceledListSlice<>(res);
9295         }
9296     }
9297
9298     @Override
9299     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9300         synchronized (this) {
9301             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9302                     "getTaskThumbnail()");
9303             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9304                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9305             if (tr != null) {
9306                 return tr.getTaskThumbnailLocked();
9307             }
9308         }
9309         return null;
9310     }
9311
9312     @Override
9313     public int addAppTask(IBinder activityToken, Intent intent,
9314             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9315         final int callingUid = Binder.getCallingUid();
9316         final long callingIdent = Binder.clearCallingIdentity();
9317
9318         try {
9319             synchronized (this) {
9320                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9321                 if (r == null) {
9322                     throw new IllegalArgumentException("Activity does not exist; token="
9323                             + activityToken);
9324                 }
9325                 ComponentName comp = intent.getComponent();
9326                 if (comp == null) {
9327                     throw new IllegalArgumentException("Intent " + intent
9328                             + " must specify explicit component");
9329                 }
9330                 if (thumbnail.getWidth() != mThumbnailWidth
9331                         || thumbnail.getHeight() != mThumbnailHeight) {
9332                     throw new IllegalArgumentException("Bad thumbnail size: got "
9333                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9334                             + mThumbnailWidth + "x" + mThumbnailHeight);
9335                 }
9336                 if (intent.getSelector() != null) {
9337                     intent.setSelector(null);
9338                 }
9339                 if (intent.getSourceBounds() != null) {
9340                     intent.setSourceBounds(null);
9341                 }
9342                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9343                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9344                         // The caller has added this as an auto-remove task...  that makes no
9345                         // sense, so turn off auto-remove.
9346                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9347                     }
9348                 }
9349                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9350                     mLastAddedTaskActivity = null;
9351                 }
9352                 ActivityInfo ainfo = mLastAddedTaskActivity;
9353                 if (ainfo == null) {
9354                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9355                             comp, 0, UserHandle.getUserId(callingUid));
9356                     if (ainfo.applicationInfo.uid != callingUid) {
9357                         throw new SecurityException(
9358                                 "Can't add task for another application: target uid="
9359                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9360                     }
9361                 }
9362
9363                 // Use the full screen as the context for the task thumbnail
9364                 final Point displaySize = new Point();
9365                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9366                 r.task.stack.getDisplaySize(displaySize);
9367                 thumbnailInfo.taskWidth = displaySize.x;
9368                 thumbnailInfo.taskHeight = displaySize.y;
9369                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9370
9371                 TaskRecord task = new TaskRecord(this,
9372                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9373                         ainfo, intent, description, thumbnailInfo);
9374
9375                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9376                 if (trimIdx >= 0) {
9377                     // If this would have caused a trim, then we'll abort because that
9378                     // means it would be added at the end of the list but then just removed.
9379                     return INVALID_TASK_ID;
9380                 }
9381
9382                 final int N = mRecentTasks.size();
9383                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9384                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9385                     tr.removedFromRecents();
9386                 }
9387
9388                 task.inRecents = true;
9389                 mRecentTasks.add(task);
9390                 r.task.stack.addTask(task, false, "addAppTask");
9391
9392                 task.setLastThumbnailLocked(thumbnail);
9393                 task.freeLastThumbnail();
9394
9395                 return task.taskId;
9396             }
9397         } finally {
9398             Binder.restoreCallingIdentity(callingIdent);
9399         }
9400     }
9401
9402     @Override
9403     public Point getAppTaskThumbnailSize() {
9404         synchronized (this) {
9405             return new Point(mThumbnailWidth,  mThumbnailHeight);
9406         }
9407     }
9408
9409     @Override
9410     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9411         synchronized (this) {
9412             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9413             if (r != null) {
9414                 r.setTaskDescription(td);
9415                 r.task.updateTaskDescription();
9416             }
9417         }
9418     }
9419
9420     @Override
9421     public void setTaskResizeable(int taskId, int resizeableMode) {
9422         synchronized (this) {
9423             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9424                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9425             if (task == null) {
9426                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9427                 return;
9428             }
9429             if (task.mResizeMode != resizeableMode) {
9430                 task.mResizeMode = resizeableMode;
9431                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9432                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9433                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9434             }
9435         }
9436     }
9437
9438     @Override
9439     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9440         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9441         long ident = Binder.clearCallingIdentity();
9442         try {
9443             synchronized (this) {
9444                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9445                 if (task == null) {
9446                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9447                     return;
9448                 }
9449                 int stackId = task.stack.mStackId;
9450                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9451                 // in crop windows resize mode or if the task size is affected by the docked stack
9452                 // changing size. No need to update configuration.
9453                 if (bounds != null && task.inCropWindowsResizeMode()
9454                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9455                     mWindowManager.scrollTask(task.taskId, bounds);
9456                     return;
9457                 }
9458
9459                 // Place the task in the right stack if it isn't there already based on
9460                 // the requested bounds.
9461                 // The stack transition logic is:
9462                 // - a null bounds on a freeform task moves that task to fullscreen
9463                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9464                 //   that task to freeform
9465                 // - otherwise the task is not moved
9466                 if (!StackId.isTaskResizeAllowed(stackId)) {
9467                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9468                 }
9469                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9470                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9471                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9472                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9473                 }
9474                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9475                 if (stackId != task.stack.mStackId) {
9476                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9477                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9478                     preserveWindow = false;
9479                 }
9480
9481                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9482                         false /* deferResume */);
9483             }
9484         } finally {
9485             Binder.restoreCallingIdentity(ident);
9486         }
9487     }
9488
9489     @Override
9490     public Rect getTaskBounds(int taskId) {
9491         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9492         long ident = Binder.clearCallingIdentity();
9493         Rect rect = new Rect();
9494         try {
9495             synchronized (this) {
9496                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9497                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9498                 if (task == null) {
9499                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9500                     return rect;
9501                 }
9502                 if (task.stack != null) {
9503                     // Return the bounds from window manager since it will be adjusted for various
9504                     // things like the presense of a docked stack for tasks that aren't resizeable.
9505                     mWindowManager.getTaskBounds(task.taskId, rect);
9506                 } else {
9507                     // Task isn't in window manager yet since it isn't associated with a stack.
9508                     // Return the persist value from activity manager
9509                     if (task.mBounds != null) {
9510                         rect.set(task.mBounds);
9511                     } else if (task.mLastNonFullscreenBounds != null) {
9512                         rect.set(task.mLastNonFullscreenBounds);
9513                     }
9514                 }
9515             }
9516         } finally {
9517             Binder.restoreCallingIdentity(ident);
9518         }
9519         return rect;
9520     }
9521
9522     @Override
9523     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9524         if (userId != UserHandle.getCallingUserId()) {
9525             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9526                     "getTaskDescriptionIcon");
9527         }
9528         final File passedIconFile = new File(filePath);
9529         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9530                 passedIconFile.getName());
9531         if (!legitIconFile.getPath().equals(filePath)
9532                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9533             throw new IllegalArgumentException("Bad file path: " + filePath
9534                     + " passed for userId " + userId);
9535         }
9536         return mRecentTasks.getTaskDescriptionIcon(filePath);
9537     }
9538
9539     @Override
9540     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9541             throws RemoteException {
9542         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9543                 opts.getCustomInPlaceResId() == 0) {
9544             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9545                     "with valid animation");
9546         }
9547         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9548         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9549                 opts.getCustomInPlaceResId());
9550         mWindowManager.executeAppTransition();
9551     }
9552
9553     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9554             boolean removeFromRecents) {
9555         if (removeFromRecents) {
9556             mRecentTasks.remove(tr);
9557             tr.removedFromRecents();
9558         }
9559         ComponentName component = tr.getBaseIntent().getComponent();
9560         if (component == null) {
9561             Slog.w(TAG, "No component for base intent of task: " + tr);
9562             return;
9563         }
9564
9565         // Find any running services associated with this app and stop if needed.
9566         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9567
9568         if (!killProcess) {
9569             return;
9570         }
9571
9572         // Determine if the process(es) for this task should be killed.
9573         final String pkg = component.getPackageName();
9574         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9575         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9576         for (int i = 0; i < pmap.size(); i++) {
9577
9578             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9579             for (int j = 0; j < uids.size(); j++) {
9580                 ProcessRecord proc = uids.valueAt(j);
9581                 if (proc.userId != tr.userId) {
9582                     // Don't kill process for a different user.
9583                     continue;
9584                 }
9585                 if (proc == mHomeProcess) {
9586                     // Don't kill the home process along with tasks from the same package.
9587                     continue;
9588                 }
9589                 if (!proc.pkgList.containsKey(pkg)) {
9590                     // Don't kill process that is not associated with this task.
9591                     continue;
9592                 }
9593
9594                 for (int k = 0; k < proc.activities.size(); k++) {
9595                     TaskRecord otherTask = proc.activities.get(k).task;
9596                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9597                         // Don't kill process(es) that has an activity in a different task that is
9598                         // also in recents.
9599                         return;
9600                     }
9601                 }
9602
9603                 if (proc.foregroundServices) {
9604                     // Don't kill process(es) with foreground service.
9605                     return;
9606                 }
9607
9608                 // Add process to kill list.
9609                 procsToKill.add(proc);
9610             }
9611         }
9612
9613         // Kill the running processes.
9614         for (int i = 0; i < procsToKill.size(); i++) {
9615             ProcessRecord pr = procsToKill.get(i);
9616             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9617                     && pr.curReceiver == null) {
9618                 pr.kill("remove task", true);
9619             } else {
9620                 // We delay killing processes that are not in the background or running a receiver.
9621                 pr.waitingToKill = "remove task";
9622             }
9623         }
9624     }
9625
9626     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9627         // Remove all tasks with activities in the specified package from the list of recent tasks
9628         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9629             TaskRecord tr = mRecentTasks.get(i);
9630             if (tr.userId != userId) continue;
9631
9632             ComponentName cn = tr.intent.getComponent();
9633             if (cn != null && cn.getPackageName().equals(packageName)) {
9634                 // If the package name matches, remove the task.
9635                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9636             }
9637         }
9638     }
9639
9640     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9641             int userId) {
9642
9643         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9644             TaskRecord tr = mRecentTasks.get(i);
9645             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9646                 continue;
9647             }
9648
9649             ComponentName cn = tr.intent.getComponent();
9650             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9651                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9652             if (sameComponent) {
9653                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9654             }
9655         }
9656     }
9657
9658     /**
9659      * Removes the task with the specified task id.
9660      *
9661      * @param taskId Identifier of the task to be removed.
9662      * @param killProcess Kill any process associated with the task if possible.
9663      * @param removeFromRecents Whether to also remove the task from recents.
9664      * @return Returns true if the given task was found and removed.
9665      */
9666     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9667             boolean removeFromRecents) {
9668         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9669                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9670         if (tr != null) {
9671             tr.removeTaskActivitiesLocked();
9672             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9673             if (tr.isPersistable) {
9674                 notifyTaskPersisterLocked(null, true);
9675             }
9676             return true;
9677         }
9678         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9679         return false;
9680     }
9681
9682     @Override
9683     public void removeStack(int stackId) {
9684         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9685         if (stackId == HOME_STACK_ID) {
9686             throw new IllegalArgumentException("Removing home stack is not allowed.");
9687         }
9688
9689         synchronized (this) {
9690             final long ident = Binder.clearCallingIdentity();
9691             try {
9692                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9693                 if (stack == null) {
9694                     return;
9695                 }
9696                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9697                 for (int i = tasks.size() - 1; i >= 0; i--) {
9698                     removeTaskByIdLocked(
9699                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9700                 }
9701             } finally {
9702                 Binder.restoreCallingIdentity(ident);
9703             }
9704         }
9705     }
9706
9707     @Override
9708     public boolean removeTask(int taskId) {
9709         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9710         synchronized (this) {
9711             final long ident = Binder.clearCallingIdentity();
9712             try {
9713                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9714             } finally {
9715                 Binder.restoreCallingIdentity(ident);
9716             }
9717         }
9718     }
9719
9720     /**
9721      * TODO: Add mController hook
9722      */
9723     @Override
9724     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9725         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9726
9727         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9728         synchronized(this) {
9729             moveTaskToFrontLocked(taskId, flags, bOptions);
9730         }
9731     }
9732
9733     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9734         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9735
9736         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9737                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9738             ActivityOptions.abort(options);
9739             return;
9740         }
9741         final long origId = Binder.clearCallingIdentity();
9742         try {
9743             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9744             if (task == null) {
9745                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9746                 return;
9747             }
9748             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9749                 mStackSupervisor.showLockTaskToast();
9750                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9751                 return;
9752             }
9753             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9754             if (prev != null && prev.isRecentsActivity()) {
9755                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9756             }
9757             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9758                     false /* forceNonResizable */);
9759         } finally {
9760             Binder.restoreCallingIdentity(origId);
9761         }
9762         ActivityOptions.abort(options);
9763     }
9764
9765     /**
9766      * Moves an activity, and all of the other activities within the same task, to the bottom
9767      * of the history stack.  The activity's order within the task is unchanged.
9768      *
9769      * @param token A reference to the activity we wish to move
9770      * @param nonRoot If false then this only works if the activity is the root
9771      *                of a task; if true it will work for any activity in a task.
9772      * @return Returns true if the move completed, false if not.
9773      */
9774     @Override
9775     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9776         enforceNotIsolatedCaller("moveActivityTaskToBack");
9777         synchronized(this) {
9778             final long origId = Binder.clearCallingIdentity();
9779             try {
9780                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9781                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9782                 if (task != null) {
9783                     if (mStackSupervisor.isLockedTask(task)) {
9784                         mStackSupervisor.showLockTaskToast();
9785                         return false;
9786                     }
9787                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9788                 }
9789             } finally {
9790                 Binder.restoreCallingIdentity(origId);
9791             }
9792         }
9793         return false;
9794     }
9795
9796     @Override
9797     public void moveTaskBackwards(int task) {
9798         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9799                 "moveTaskBackwards()");
9800
9801         synchronized(this) {
9802             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9803                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9804                 return;
9805             }
9806             final long origId = Binder.clearCallingIdentity();
9807             moveTaskBackwardsLocked(task);
9808             Binder.restoreCallingIdentity(origId);
9809         }
9810     }
9811
9812     private final void moveTaskBackwardsLocked(int task) {
9813         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9814     }
9815
9816     @Override
9817     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9818             IActivityContainerCallback callback) throws RemoteException {
9819         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9820         synchronized (this) {
9821             if (parentActivityToken == null) {
9822                 throw new IllegalArgumentException("parent token must not be null");
9823             }
9824             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9825             if (r == null) {
9826                 return null;
9827             }
9828             if (callback == null) {
9829                 throw new IllegalArgumentException("callback must not be null");
9830             }
9831             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9832         }
9833     }
9834
9835     @Override
9836     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9837         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9838         synchronized (this) {
9839             mStackSupervisor.deleteActivityContainer(container);
9840         }
9841     }
9842
9843     @Override
9844     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9845         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9846         synchronized (this) {
9847             final int stackId = mStackSupervisor.getNextStackId();
9848             final ActivityStack stack =
9849                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9850             if (stack == null) {
9851                 return null;
9852             }
9853             return stack.mActivityContainer;
9854         }
9855     }
9856
9857     @Override
9858     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9859         synchronized (this) {
9860             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9861             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9862                 return stack.mActivityContainer.getDisplayId();
9863             }
9864             return Display.DEFAULT_DISPLAY;
9865         }
9866     }
9867
9868     @Override
9869     public int getActivityStackId(IBinder token) throws RemoteException {
9870         synchronized (this) {
9871             ActivityStack stack = ActivityRecord.getStackLocked(token);
9872             if (stack == null) {
9873                 return INVALID_STACK_ID;
9874             }
9875             return stack.mStackId;
9876         }
9877     }
9878
9879     @Override
9880     public void exitFreeformMode(IBinder token) throws RemoteException {
9881         synchronized (this) {
9882             long ident = Binder.clearCallingIdentity();
9883             try {
9884                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9885                 if (r == null) {
9886                     throw new IllegalArgumentException(
9887                             "exitFreeformMode: No activity record matching token=" + token);
9888                 }
9889                 final ActivityStack stack = r.getStackLocked(token);
9890                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9891                     throw new IllegalStateException(
9892                             "exitFreeformMode: You can only go fullscreen from freeform.");
9893                 }
9894                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9895                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9896                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9897             } finally {
9898                 Binder.restoreCallingIdentity(ident);
9899             }
9900         }
9901     }
9902
9903     @Override
9904     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9905         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9906         if (stackId == HOME_STACK_ID) {
9907             throw new IllegalArgumentException(
9908                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9909         }
9910         synchronized (this) {
9911             long ident = Binder.clearCallingIdentity();
9912             try {
9913                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9914                         + " to stackId=" + stackId + " toTop=" + toTop);
9915                 if (stackId == DOCKED_STACK_ID) {
9916                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9917                             null /* initialBounds */);
9918                 }
9919                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9920                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9921                 if (result && stackId == DOCKED_STACK_ID) {
9922                     // If task moved to docked stack - show recents if needed.
9923                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9924                             "moveTaskToDockedStack");
9925                 }
9926             } finally {
9927                 Binder.restoreCallingIdentity(ident);
9928             }
9929         }
9930     }
9931
9932     @Override
9933     public void swapDockedAndFullscreenStack() throws RemoteException {
9934         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9935         synchronized (this) {
9936             long ident = Binder.clearCallingIdentity();
9937             try {
9938                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9939                         FULLSCREEN_WORKSPACE_STACK_ID);
9940                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9941                         : null;
9942                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9943                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9944                         : null;
9945                 if (topTask == null || tasks == null || tasks.size() == 0) {
9946                     Slog.w(TAG,
9947                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9948                     return;
9949                 }
9950
9951                 // TODO: App transition
9952                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9953
9954                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9955                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9956                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9957                         ANIMATE, true /* deferResume */);
9958                 final int size = tasks.size();
9959                 for (int i = 0; i < size; i++) {
9960                     final int id = tasks.get(i).taskId;
9961                     if (id == topTask.taskId) {
9962                         continue;
9963                     }
9964                     mStackSupervisor.moveTaskToStackLocked(id,
9965                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9966                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9967                 }
9968
9969                 // Because we deferred the resume, to avoid conflicts with stack switches while
9970                 // resuming, we need to do it after all the tasks are moved.
9971                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9972                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9973
9974                 mWindowManager.executeAppTransition();
9975             } finally {
9976                 Binder.restoreCallingIdentity(ident);
9977             }
9978         }
9979     }
9980
9981     /**
9982      * Moves the input task to the docked stack.
9983      *
9984      * @param taskId Id of task to move.
9985      * @param createMode The mode the docked stack should be created in if it doesn't exist
9986      *                   already. See
9987      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9988      *                   and
9989      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9990      * @param toTop If the task and stack should be moved to the top.
9991      * @param animate Whether we should play an animation for the moving the task
9992      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9993      *                      docked stack. Pass {@code null} to use default bounds.
9994      */
9995     @Override
9996     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9997             Rect initialBounds, boolean moveHomeStackFront) {
9998         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9999         synchronized (this) {
10000             long ident = Binder.clearCallingIdentity();
10001             try {
10002                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10003                         + " to createMode=" + createMode + " toTop=" + toTop);
10004                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10005                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10006                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10007                         animate, DEFER_RESUME);
10008                 if (moved) {
10009                     if (moveHomeStackFront) {
10010                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10011                     }
10012                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10013                 }
10014                 return moved;
10015             } finally {
10016                 Binder.restoreCallingIdentity(ident);
10017             }
10018         }
10019     }
10020
10021     /**
10022      * Moves the top activity in the input stackId to the pinned stack.
10023      *
10024      * @param stackId Id of stack to move the top activity to pinned stack.
10025      * @param bounds Bounds to use for pinned stack.
10026      *
10027      * @return True if the top activity of the input stack was successfully moved to the pinned
10028      *          stack.
10029      */
10030     @Override
10031     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10032         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10033         synchronized (this) {
10034             if (!mSupportsPictureInPicture) {
10035                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10036                         + "Device doesn't support picture-in-pciture mode");
10037             }
10038
10039             long ident = Binder.clearCallingIdentity();
10040             try {
10041                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10042             } finally {
10043                 Binder.restoreCallingIdentity(ident);
10044             }
10045         }
10046     }
10047
10048     @Override
10049     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10050             boolean preserveWindows, boolean animate, int animationDuration) {
10051         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10052         long ident = Binder.clearCallingIdentity();
10053         try {
10054             synchronized (this) {
10055                 if (animate) {
10056                     if (stackId == PINNED_STACK_ID) {
10057                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10058                     } else {
10059                         throw new IllegalArgumentException("Stack: " + stackId
10060                                 + " doesn't support animated resize.");
10061                     }
10062                 } else {
10063                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10064                             null /* tempTaskInsetBounds */, preserveWindows,
10065                             allowResizeInDockedMode, !DEFER_RESUME);
10066                 }
10067             }
10068         } finally {
10069             Binder.restoreCallingIdentity(ident);
10070         }
10071     }
10072
10073     @Override
10074     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10075             Rect tempDockedTaskInsetBounds,
10076             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10077         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10078                 "resizeDockedStack()");
10079         long ident = Binder.clearCallingIdentity();
10080         try {
10081             synchronized (this) {
10082                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10083                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10084                         PRESERVE_WINDOWS);
10085             }
10086         } finally {
10087             Binder.restoreCallingIdentity(ident);
10088         }
10089     }
10090
10091     @Override
10092     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10093         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10094                 "resizePinnedStack()");
10095         final long ident = Binder.clearCallingIdentity();
10096         try {
10097             synchronized (this) {
10098                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10099             }
10100         } finally {
10101             Binder.restoreCallingIdentity(ident);
10102         }
10103     }
10104
10105     @Override
10106     public void positionTaskInStack(int taskId, int stackId, int position) {
10107         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10108         if (stackId == HOME_STACK_ID) {
10109             throw new IllegalArgumentException(
10110                     "positionTaskInStack: Attempt to change the position of task "
10111                     + taskId + " in/to home stack");
10112         }
10113         synchronized (this) {
10114             long ident = Binder.clearCallingIdentity();
10115             try {
10116                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10117                         "positionTaskInStack: positioning task=" + taskId
10118                         + " in stackId=" + stackId + " at position=" + position);
10119                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10120             } finally {
10121                 Binder.restoreCallingIdentity(ident);
10122             }
10123         }
10124     }
10125
10126     @Override
10127     public List<StackInfo> getAllStackInfos() {
10128         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10129         long ident = Binder.clearCallingIdentity();
10130         try {
10131             synchronized (this) {
10132                 return mStackSupervisor.getAllStackInfosLocked();
10133             }
10134         } finally {
10135             Binder.restoreCallingIdentity(ident);
10136         }
10137     }
10138
10139     @Override
10140     public StackInfo getStackInfo(int stackId) {
10141         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10142         long ident = Binder.clearCallingIdentity();
10143         try {
10144             synchronized (this) {
10145                 return mStackSupervisor.getStackInfoLocked(stackId);
10146             }
10147         } finally {
10148             Binder.restoreCallingIdentity(ident);
10149         }
10150     }
10151
10152     @Override
10153     public boolean isInHomeStack(int taskId) {
10154         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10155         long ident = Binder.clearCallingIdentity();
10156         try {
10157             synchronized (this) {
10158                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10159                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10160                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10161             }
10162         } finally {
10163             Binder.restoreCallingIdentity(ident);
10164         }
10165     }
10166
10167     @Override
10168     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10169         synchronized(this) {
10170             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10171         }
10172     }
10173
10174     @Override
10175     public void updateDeviceOwner(String packageName) {
10176         final int callingUid = Binder.getCallingUid();
10177         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10178             throw new SecurityException("updateDeviceOwner called from non-system process");
10179         }
10180         synchronized (this) {
10181             mDeviceOwnerName = packageName;
10182         }
10183     }
10184
10185     @Override
10186     public void updateLockTaskPackages(int userId, String[] packages) {
10187         final int callingUid = Binder.getCallingUid();
10188         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10189             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10190                     "updateLockTaskPackages()");
10191         }
10192         synchronized (this) {
10193             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10194                     Arrays.toString(packages));
10195             mLockTaskPackages.put(userId, packages);
10196             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10197         }
10198     }
10199
10200
10201     void startLockTaskModeLocked(TaskRecord task) {
10202         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10203         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10204             return;
10205         }
10206
10207         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10208         // is initiated by system after the pinning request was shown and locked mode is initiated
10209         // by an authorized app directly
10210         final int callingUid = Binder.getCallingUid();
10211         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10212         long ident = Binder.clearCallingIdentity();
10213         try {
10214             if (!isSystemInitiated) {
10215                 task.mLockTaskUid = callingUid;
10216                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10217                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10218                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10219                     StatusBarManagerInternal statusBarManager =
10220                             LocalServices.getService(StatusBarManagerInternal.class);
10221                     if (statusBarManager != null) {
10222                         statusBarManager.showScreenPinningRequest(task.taskId);
10223                     }
10224                     return;
10225                 }
10226
10227                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10228                 if (stack == null || task != stack.topTask()) {
10229                     throw new IllegalArgumentException("Invalid task, not in foreground");
10230                 }
10231             }
10232             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10233                     "Locking fully");
10234             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10235                     ActivityManager.LOCK_TASK_MODE_PINNED :
10236                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10237                     "startLockTask", true);
10238         } finally {
10239             Binder.restoreCallingIdentity(ident);
10240         }
10241     }
10242
10243     @Override
10244     public void startLockTaskMode(int taskId) {
10245         synchronized (this) {
10246             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10247             if (task != null) {
10248                 startLockTaskModeLocked(task);
10249             }
10250         }
10251     }
10252
10253     @Override
10254     public void startLockTaskMode(IBinder token) {
10255         synchronized (this) {
10256             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10257             if (r == null) {
10258                 return;
10259             }
10260             final TaskRecord task = r.task;
10261             if (task != null) {
10262                 startLockTaskModeLocked(task);
10263             }
10264         }
10265     }
10266
10267     @Override
10268     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10269         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10270         // This makes inner call to look as if it was initiated by system.
10271         long ident = Binder.clearCallingIdentity();
10272         try {
10273             synchronized (this) {
10274                 startLockTaskMode(taskId);
10275             }
10276         } finally {
10277             Binder.restoreCallingIdentity(ident);
10278         }
10279     }
10280
10281     @Override
10282     public void stopLockTaskMode() {
10283         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10284         if (lockTask == null) {
10285             // Our work here is done.
10286             return;
10287         }
10288
10289         final int callingUid = Binder.getCallingUid();
10290         final int lockTaskUid = lockTask.mLockTaskUid;
10291         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10292         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10293             // Done.
10294             return;
10295         } else {
10296             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10297             // It is possible lockTaskMode was started by the system process because
10298             // android:lockTaskMode is set to a locking value in the application manifest
10299             // instead of the app calling startLockTaskMode. In this case
10300             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10301             // {@link TaskRecord.effectiveUid} instead. Also caller with
10302             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10303             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10304                     && callingUid != lockTaskUid
10305                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10306                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10307                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10308             }
10309         }
10310         long ident = Binder.clearCallingIdentity();
10311         try {
10312             Log.d(TAG, "stopLockTaskMode");
10313             // Stop lock task
10314             synchronized (this) {
10315                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10316                         "stopLockTask", true);
10317             }
10318             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10319             if (tm != null) {
10320                 tm.showInCallScreen(false);
10321             }
10322         } finally {
10323             Binder.restoreCallingIdentity(ident);
10324         }
10325     }
10326
10327     /**
10328      * This API should be called by SystemUI only when user perform certain action to dismiss
10329      * lock task mode. We should only dismiss pinned lock task mode in this case.
10330      */
10331     @Override
10332     public void stopSystemLockTaskMode() throws RemoteException {
10333         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10334             stopLockTaskMode();
10335         } else {
10336             mStackSupervisor.showLockTaskToast();
10337         }
10338     }
10339
10340     @Override
10341     public boolean isInLockTaskMode() {
10342         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10343     }
10344
10345     @Override
10346     public int getLockTaskModeState() {
10347         synchronized (this) {
10348             return mStackSupervisor.getLockTaskModeState();
10349         }
10350     }
10351
10352     @Override
10353     public void showLockTaskEscapeMessage(IBinder token) {
10354         synchronized (this) {
10355             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10356             if (r == null) {
10357                 return;
10358             }
10359             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10360         }
10361     }
10362
10363     // =========================================================
10364     // CONTENT PROVIDERS
10365     // =========================================================
10366
10367     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10368         List<ProviderInfo> providers = null;
10369         try {
10370             providers = AppGlobals.getPackageManager()
10371                     .queryContentProviders(app.processName, app.uid,
10372                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10373                                     | MATCH_DEBUG_TRIAGED_MISSING)
10374                     .getList();
10375         } catch (RemoteException ex) {
10376         }
10377         if (DEBUG_MU) Slog.v(TAG_MU,
10378                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10379         int userId = app.userId;
10380         if (providers != null) {
10381             int N = providers.size();
10382             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10383             for (int i=0; i<N; i++) {
10384                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10385                 ProviderInfo cpi =
10386                     (ProviderInfo)providers.get(i);
10387                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10388                         cpi.name, cpi.flags);
10389                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10390                     // This is a singleton provider, but a user besides the
10391                     // default user is asking to initialize a process it runs
10392                     // in...  well, no, it doesn't actually run in this process,
10393                     // it runs in the process of the default user.  Get rid of it.
10394                     providers.remove(i);
10395                     N--;
10396                     i--;
10397                     continue;
10398                 }
10399
10400                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10401                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10402                 if (cpr == null) {
10403                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10404                     mProviderMap.putProviderByClass(comp, cpr);
10405                 }
10406                 if (DEBUG_MU) Slog.v(TAG_MU,
10407                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10408                 app.pubProviders.put(cpi.name, cpr);
10409                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10410                     // Don't add this if it is a platform component that is marked
10411                     // to run in multiple processes, because this is actually
10412                     // part of the framework so doesn't make sense to track as a
10413                     // separate apk in the process.
10414                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10415                             mProcessStats);
10416                 }
10417                 notifyPackageUse(cpi.applicationInfo.packageName,
10418                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10419             }
10420         }
10421         return providers;
10422     }
10423
10424     /**
10425      * Check if the calling UID has a possible chance at accessing the provider
10426      * at the given authority and user.
10427      */
10428     public String checkContentProviderAccess(String authority, int userId) {
10429         if (userId == UserHandle.USER_ALL) {
10430             mContext.enforceCallingOrSelfPermission(
10431                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10432             userId = UserHandle.getCallingUserId();
10433         }
10434
10435         ProviderInfo cpi = null;
10436         try {
10437             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10438                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10439                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10440                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10441                     userId);
10442         } catch (RemoteException ignored) {
10443         }
10444         if (cpi == null) {
10445             // TODO: make this an outright failure in a future platform release;
10446             // until then anonymous content notifications are unprotected
10447             //return "Failed to find provider " + authority + " for user " + userId;
10448             return null;
10449         }
10450
10451         ProcessRecord r = null;
10452         synchronized (mPidsSelfLocked) {
10453             r = mPidsSelfLocked.get(Binder.getCallingPid());
10454         }
10455         if (r == null) {
10456             return "Failed to find PID " + Binder.getCallingPid();
10457         }
10458
10459         synchronized (this) {
10460             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10461         }
10462     }
10463
10464     /**
10465      * Check if {@link ProcessRecord} has a possible chance at accessing the
10466      * given {@link ProviderInfo}. Final permission checking is always done
10467      * in {@link ContentProvider}.
10468      */
10469     private final String checkContentProviderPermissionLocked(
10470             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10471         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10472         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10473         boolean checkedGrants = false;
10474         if (checkUser) {
10475             // Looking for cross-user grants before enforcing the typical cross-users permissions
10476             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10477             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10478                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10479                     return null;
10480                 }
10481                 checkedGrants = true;
10482             }
10483             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10484                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10485             if (userId != tmpTargetUserId) {
10486                 // When we actually went to determine the final targer user ID, this ended
10487                 // up different than our initial check for the authority.  This is because
10488                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10489                 // SELF.  So we need to re-check the grants again.
10490                 checkedGrants = false;
10491             }
10492         }
10493         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10494                 cpi.applicationInfo.uid, cpi.exported)
10495                 == PackageManager.PERMISSION_GRANTED) {
10496             return null;
10497         }
10498         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10499                 cpi.applicationInfo.uid, cpi.exported)
10500                 == PackageManager.PERMISSION_GRANTED) {
10501             return null;
10502         }
10503
10504         PathPermission[] pps = cpi.pathPermissions;
10505         if (pps != null) {
10506             int i = pps.length;
10507             while (i > 0) {
10508                 i--;
10509                 PathPermission pp = pps[i];
10510                 String pprperm = pp.getReadPermission();
10511                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10512                         cpi.applicationInfo.uid, cpi.exported)
10513                         == PackageManager.PERMISSION_GRANTED) {
10514                     return null;
10515                 }
10516                 String ppwperm = pp.getWritePermission();
10517                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10518                         cpi.applicationInfo.uid, cpi.exported)
10519                         == PackageManager.PERMISSION_GRANTED) {
10520                     return null;
10521                 }
10522             }
10523         }
10524         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10525             return null;
10526         }
10527
10528         String msg;
10529         if (!cpi.exported) {
10530             msg = "Permission Denial: opening provider " + cpi.name
10531                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10532                     + ", uid=" + callingUid + ") that is not exported from uid "
10533                     + cpi.applicationInfo.uid;
10534         } else {
10535             msg = "Permission Denial: opening provider " + cpi.name
10536                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10537                     + ", uid=" + callingUid + ") requires "
10538                     + cpi.readPermission + " or " + cpi.writePermission;
10539         }
10540         Slog.w(TAG, msg);
10541         return msg;
10542     }
10543
10544     /**
10545      * Returns if the ContentProvider has granted a uri to callingUid
10546      */
10547     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10548         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10549         if (perms != null) {
10550             for (int i=perms.size()-1; i>=0; i--) {
10551                 GrantUri grantUri = perms.keyAt(i);
10552                 if (grantUri.sourceUserId == userId || !checkUser) {
10553                     if (matchesProvider(grantUri.uri, cpi)) {
10554                         return true;
10555                     }
10556                 }
10557             }
10558         }
10559         return false;
10560     }
10561
10562     /**
10563      * Returns true if the uri authority is one of the authorities specified in the provider.
10564      */
10565     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10566         String uriAuth = uri.getAuthority();
10567         String cpiAuth = cpi.authority;
10568         if (cpiAuth.indexOf(';') == -1) {
10569             return cpiAuth.equals(uriAuth);
10570         }
10571         String[] cpiAuths = cpiAuth.split(";");
10572         int length = cpiAuths.length;
10573         for (int i = 0; i < length; i++) {
10574             if (cpiAuths[i].equals(uriAuth)) return true;
10575         }
10576         return false;
10577     }
10578
10579     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10580             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10581         if (r != null) {
10582             for (int i=0; i<r.conProviders.size(); i++) {
10583                 ContentProviderConnection conn = r.conProviders.get(i);
10584                 if (conn.provider == cpr) {
10585                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10586                             "Adding provider requested by "
10587                             + r.processName + " from process "
10588                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10589                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10590                     if (stable) {
10591                         conn.stableCount++;
10592                         conn.numStableIncs++;
10593                     } else {
10594                         conn.unstableCount++;
10595                         conn.numUnstableIncs++;
10596                     }
10597                     return conn;
10598                 }
10599             }
10600             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10601             if (stable) {
10602                 conn.stableCount = 1;
10603                 conn.numStableIncs = 1;
10604             } else {
10605                 conn.unstableCount = 1;
10606                 conn.numUnstableIncs = 1;
10607             }
10608             cpr.connections.add(conn);
10609             r.conProviders.add(conn);
10610             startAssociationLocked(r.uid, r.processName, r.curProcState,
10611                     cpr.uid, cpr.name, cpr.info.processName);
10612             return conn;
10613         }
10614         cpr.addExternalProcessHandleLocked(externalProcessToken);
10615         return null;
10616     }
10617
10618     boolean decProviderCountLocked(ContentProviderConnection conn,
10619             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10620         if (conn != null) {
10621             cpr = conn.provider;
10622             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10623                     "Removing provider requested by "
10624                     + conn.client.processName + " from process "
10625                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10626                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10627             if (stable) {
10628                 conn.stableCount--;
10629             } else {
10630                 conn.unstableCount--;
10631             }
10632             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10633                 cpr.connections.remove(conn);
10634                 conn.client.conProviders.remove(conn);
10635                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10636                     // The client is more important than last activity -- note the time this
10637                     // is happening, so we keep the old provider process around a bit as last
10638                     // activity to avoid thrashing it.
10639                     if (cpr.proc != null) {
10640                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10641                     }
10642                 }
10643                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10644                 return true;
10645             }
10646             return false;
10647         }
10648         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10649         return false;
10650     }
10651
10652     private void checkTime(long startTime, String where) {
10653         long now = SystemClock.uptimeMillis();
10654         if ((now-startTime) > 50) {
10655             // If we are taking more than 50ms, log about it.
10656             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10657         }
10658     }
10659
10660     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10661             PROC_SPACE_TERM,
10662             PROC_SPACE_TERM|PROC_PARENS,
10663             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10664     };
10665
10666     private final long[] mProcessStateStatsLongs = new long[1];
10667
10668     boolean isProcessAliveLocked(ProcessRecord proc) {
10669         if (proc.procStatFile == null) {
10670             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10671         }
10672         mProcessStateStatsLongs[0] = 0;
10673         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10674                 mProcessStateStatsLongs, null)) {
10675             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10676             return false;
10677         }
10678         final long state = mProcessStateStatsLongs[0];
10679         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10680                 + (char)state);
10681         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10682     }
10683
10684     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10685             String name, IBinder token, boolean stable, int userId) {
10686         ContentProviderRecord cpr;
10687         ContentProviderConnection conn = null;
10688         ProviderInfo cpi = null;
10689
10690         synchronized(this) {
10691             long startTime = SystemClock.uptimeMillis();
10692
10693             ProcessRecord r = null;
10694             if (caller != null) {
10695                 r = getRecordForAppLocked(caller);
10696                 if (r == null) {
10697                     throw new SecurityException(
10698                             "Unable to find app for caller " + caller
10699                           + " (pid=" + Binder.getCallingPid()
10700                           + ") when getting content provider " + name);
10701                 }
10702             }
10703
10704             boolean checkCrossUser = true;
10705
10706             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10707
10708             // First check if this content provider has been published...
10709             cpr = mProviderMap.getProviderByName(name, userId);
10710             // If that didn't work, check if it exists for user 0 and then
10711             // verify that it's a singleton provider before using it.
10712             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10713                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10714                 if (cpr != null) {
10715                     cpi = cpr.info;
10716                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10717                             cpi.name, cpi.flags)
10718                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10719                         userId = UserHandle.USER_SYSTEM;
10720                         checkCrossUser = false;
10721                     } else {
10722                         cpr = null;
10723                         cpi = null;
10724                     }
10725                 }
10726             }
10727
10728             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10729             if (providerRunning) {
10730                 cpi = cpr.info;
10731                 String msg;
10732                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10733                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10734                         != null) {
10735                     throw new SecurityException(msg);
10736                 }
10737                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10738
10739                 if (r != null && cpr.canRunHere(r)) {
10740                     // This provider has been published or is in the process
10741                     // of being published...  but it is also allowed to run
10742                     // in the caller's process, so don't make a connection
10743                     // and just let the caller instantiate its own instance.
10744                     ContentProviderHolder holder = cpr.newHolder(null);
10745                     // don't give caller the provider object, it needs
10746                     // to make its own.
10747                     holder.provider = null;
10748                     return holder;
10749                 }
10750
10751                 final long origId = Binder.clearCallingIdentity();
10752
10753                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10754
10755                 // In this case the provider instance already exists, so we can
10756                 // return it right away.
10757                 conn = incProviderCountLocked(r, cpr, token, stable);
10758                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10759                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10760                         // If this is a perceptible app accessing the provider,
10761                         // make sure to count it as being accessed and thus
10762                         // back up on the LRU list.  This is good because
10763                         // content providers are often expensive to start.
10764                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10765                         updateLruProcessLocked(cpr.proc, false, null);
10766                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10767                     }
10768                 }
10769
10770                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10771                 final int verifiedAdj = cpr.proc.verifiedAdj;
10772                 boolean success = updateOomAdjLocked(cpr.proc);
10773                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10774                 // if the process has been successfully adjusted.  So to reduce races with
10775                 // it, we will check whether the process still exists.  Note that this doesn't
10776                 // completely get rid of races with LMK killing the process, but should make
10777                 // them much smaller.
10778                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10779                     success = false;
10780                 }
10781                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10782                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10783                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10784                 // NOTE: there is still a race here where a signal could be
10785                 // pending on the process even though we managed to update its
10786                 // adj level.  Not sure what to do about this, but at least
10787                 // the race is now smaller.
10788                 if (!success) {
10789                     // Uh oh...  it looks like the provider's process
10790                     // has been killed on us.  We need to wait for a new
10791                     // process to be started, and make sure its death
10792                     // doesn't kill our process.
10793                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10794                             + " is crashing; detaching " + r);
10795                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10796                     checkTime(startTime, "getContentProviderImpl: before appDied");
10797                     appDiedLocked(cpr.proc);
10798                     checkTime(startTime, "getContentProviderImpl: after appDied");
10799                     if (!lastRef) {
10800                         // This wasn't the last ref our process had on
10801                         // the provider...  we have now been killed, bail.
10802                         return null;
10803                     }
10804                     providerRunning = false;
10805                     conn = null;
10806                 } else {
10807                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10808                 }
10809
10810                 Binder.restoreCallingIdentity(origId);
10811             }
10812
10813             if (!providerRunning) {
10814                 try {
10815                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10816                     cpi = AppGlobals.getPackageManager().
10817                         resolveContentProvider(name,
10818                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10819                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10820                 } catch (RemoteException ex) {
10821                 }
10822                 if (cpi == null) {
10823                     return null;
10824                 }
10825                 // If the provider is a singleton AND
10826                 // (it's a call within the same user || the provider is a
10827                 // privileged app)
10828                 // Then allow connecting to the singleton provider
10829                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10830                         cpi.name, cpi.flags)
10831                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10832                 if (singleton) {
10833                     userId = UserHandle.USER_SYSTEM;
10834                 }
10835                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10836                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10837
10838                 String msg;
10839                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10840                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10841                         != null) {
10842                     throw new SecurityException(msg);
10843                 }
10844                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10845
10846                 if (!mProcessesReady
10847                         && !cpi.processName.equals("system")) {
10848                     // If this content provider does not run in the system
10849                     // process, and the system is not yet ready to run other
10850                     // processes, then fail fast instead of hanging.
10851                     throw new IllegalArgumentException(
10852                             "Attempt to launch content provider before system ready");
10853                 }
10854
10855                 // Make sure that the user who owns this provider is running.  If not,
10856                 // we don't want to allow it to run.
10857                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10858                     Slog.w(TAG, "Unable to launch app "
10859                             + cpi.applicationInfo.packageName + "/"
10860                             + cpi.applicationInfo.uid + " for provider "
10861                             + name + ": user " + userId + " is stopped");
10862                     return null;
10863                 }
10864
10865                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10866                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10867                 cpr = mProviderMap.getProviderByClass(comp, userId);
10868                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10869                 final boolean firstClass = cpr == null;
10870                 if (firstClass) {
10871                     final long ident = Binder.clearCallingIdentity();
10872
10873                     // If permissions need a review before any of the app components can run,
10874                     // we return no provider and launch a review activity if the calling app
10875                     // is in the foreground.
10876                     if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10877                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10878                             return null;
10879                         }
10880                     }
10881
10882                     try {
10883                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10884                         ApplicationInfo ai =
10885                             AppGlobals.getPackageManager().
10886                                 getApplicationInfo(
10887                                         cpi.applicationInfo.packageName,
10888                                         STOCK_PM_FLAGS, userId);
10889                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10890                         if (ai == null) {
10891                             Slog.w(TAG, "No package info for content provider "
10892                                     + cpi.name);
10893                             return null;
10894                         }
10895                         ai = getAppInfoForUser(ai, userId);
10896                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10897                     } catch (RemoteException ex) {
10898                         // pm is in same process, this will never happen.
10899                     } finally {
10900                         Binder.restoreCallingIdentity(ident);
10901                     }
10902                 }
10903
10904                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10905
10906                 if (r != null && cpr.canRunHere(r)) {
10907                     // If this is a multiprocess provider, then just return its
10908                     // info and allow the caller to instantiate it.  Only do
10909                     // this if the provider is the same user as the caller's
10910                     // process, or can run as root (so can be in any process).
10911                     return cpr.newHolder(null);
10912                 }
10913
10914                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10915                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10916                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10917
10918                 // This is single process, and our app is now connecting to it.
10919                 // See if we are already in the process of launching this
10920                 // provider.
10921                 final int N = mLaunchingProviders.size();
10922                 int i;
10923                 for (i = 0; i < N; i++) {
10924                     if (mLaunchingProviders.get(i) == cpr) {
10925                         break;
10926                     }
10927                 }
10928
10929                 // If the provider is not already being launched, then get it
10930                 // started.
10931                 if (i >= N) {
10932                     final long origId = Binder.clearCallingIdentity();
10933
10934                     try {
10935                         // Content provider is now in use, its package can't be stopped.
10936                         try {
10937                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10938                             AppGlobals.getPackageManager().setPackageStoppedState(
10939                                     cpr.appInfo.packageName, false, userId);
10940                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10941                         } catch (RemoteException e) {
10942                         } catch (IllegalArgumentException e) {
10943                             Slog.w(TAG, "Failed trying to unstop package "
10944                                     + cpr.appInfo.packageName + ": " + e);
10945                         }
10946
10947                         // Use existing process if already started
10948                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10949                         ProcessRecord proc = getProcessRecordLocked(
10950                                 cpi.processName, cpr.appInfo.uid, false);
10951                         if (proc != null && proc.thread != null && !proc.killed) {
10952                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10953                                     "Installing in existing process " + proc);
10954                             if (!proc.pubProviders.containsKey(cpi.name)) {
10955                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10956                                 proc.pubProviders.put(cpi.name, cpr);
10957                                 try {
10958                                     proc.thread.scheduleInstallProvider(cpi);
10959                                 } catch (RemoteException e) {
10960                                 }
10961                             }
10962                         } else {
10963                             checkTime(startTime, "getContentProviderImpl: before start process");
10964                             proc = startProcessLocked(cpi.processName,
10965                                     cpr.appInfo, false, 0, "content provider",
10966                                     new ComponentName(cpi.applicationInfo.packageName,
10967                                             cpi.name), false, false, false);
10968                             checkTime(startTime, "getContentProviderImpl: after start process");
10969                             if (proc == null) {
10970                                 Slog.w(TAG, "Unable to launch app "
10971                                         + cpi.applicationInfo.packageName + "/"
10972                                         + cpi.applicationInfo.uid + " for provider "
10973                                         + name + ": process is bad");
10974                                 return null;
10975                             }
10976                         }
10977                         cpr.launchingApp = proc;
10978                         mLaunchingProviders.add(cpr);
10979                     } finally {
10980                         Binder.restoreCallingIdentity(origId);
10981                     }
10982                 }
10983
10984                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10985
10986                 // Make sure the provider is published (the same provider class
10987                 // may be published under multiple names).
10988                 if (firstClass) {
10989                     mProviderMap.putProviderByClass(comp, cpr);
10990                 }
10991
10992                 mProviderMap.putProviderByName(name, cpr);
10993                 conn = incProviderCountLocked(r, cpr, token, stable);
10994                 if (conn != null) {
10995                     conn.waiting = true;
10996                 }
10997             }
10998             checkTime(startTime, "getContentProviderImpl: done!");
10999         }
11000
11001         // Wait for the provider to be published...
11002         synchronized (cpr) {
11003             while (cpr.provider == null) {
11004                 if (cpr.launchingApp == null) {
11005                     Slog.w(TAG, "Unable to launch app "
11006                             + cpi.applicationInfo.packageName + "/"
11007                             + cpi.applicationInfo.uid + " for provider "
11008                             + name + ": launching app became null");
11009                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11010                             UserHandle.getUserId(cpi.applicationInfo.uid),
11011                             cpi.applicationInfo.packageName,
11012                             cpi.applicationInfo.uid, name);
11013                     return null;
11014                 }
11015                 try {
11016                     if (DEBUG_MU) Slog.v(TAG_MU,
11017                             "Waiting to start provider " + cpr
11018                             + " launchingApp=" + cpr.launchingApp);
11019                     if (conn != null) {
11020                         conn.waiting = true;
11021                     }
11022                     cpr.wait();
11023                 } catch (InterruptedException ex) {
11024                 } finally {
11025                     if (conn != null) {
11026                         conn.waiting = false;
11027                     }
11028                 }
11029             }
11030         }
11031         return cpr != null ? cpr.newHolder(conn) : null;
11032     }
11033
11034     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11035             ProcessRecord r, final int userId) {
11036         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11037                 cpi.packageName, userId)) {
11038
11039             final boolean callerForeground = r == null || r.setSchedGroup
11040                     != ProcessList.SCHED_GROUP_BACKGROUND;
11041
11042             // Show a permission review UI only for starting from a foreground app
11043             if (!callerForeground) {
11044                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11045                         + cpi.packageName + " requires a permissions review");
11046                 return false;
11047             }
11048
11049             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11050             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11051                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11052             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11053
11054             if (DEBUG_PERMISSIONS_REVIEW) {
11055                 Slog.i(TAG, "u" + userId + " Launching permission review "
11056                         + "for package " + cpi.packageName);
11057             }
11058
11059             final UserHandle userHandle = new UserHandle(userId);
11060             mHandler.post(new Runnable() {
11061                 @Override
11062                 public void run() {
11063                     mContext.startActivityAsUser(intent, userHandle);
11064                 }
11065             });
11066
11067             return false;
11068         }
11069
11070         return true;
11071     }
11072
11073     PackageManagerInternal getPackageManagerInternalLocked() {
11074         if (mPackageManagerInt == null) {
11075             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11076         }
11077         return mPackageManagerInt;
11078     }
11079
11080     @Override
11081     public final ContentProviderHolder getContentProvider(
11082             IApplicationThread caller, String name, int userId, boolean stable) {
11083         enforceNotIsolatedCaller("getContentProvider");
11084         if (caller == null) {
11085             String msg = "null IApplicationThread when getting content provider "
11086                     + name;
11087             Slog.w(TAG, msg);
11088             throw new SecurityException(msg);
11089         }
11090         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11091         // with cross-user grant.
11092         return getContentProviderImpl(caller, name, null, stable, userId);
11093     }
11094
11095     public ContentProviderHolder getContentProviderExternal(
11096             String name, int userId, IBinder token) {
11097         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11098             "Do not have permission in call getContentProviderExternal()");
11099         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11100                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11101         return getContentProviderExternalUnchecked(name, token, userId);
11102     }
11103
11104     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11105             IBinder token, int userId) {
11106         return getContentProviderImpl(null, name, token, true, userId);
11107     }
11108
11109     /**
11110      * Drop a content provider from a ProcessRecord's bookkeeping
11111      */
11112     public void removeContentProvider(IBinder connection, boolean stable) {
11113         enforceNotIsolatedCaller("removeContentProvider");
11114         long ident = Binder.clearCallingIdentity();
11115         try {
11116             synchronized (this) {
11117                 ContentProviderConnection conn;
11118                 try {
11119                     conn = (ContentProviderConnection)connection;
11120                 } catch (ClassCastException e) {
11121                     String msg ="removeContentProvider: " + connection
11122                             + " not a ContentProviderConnection";
11123                     Slog.w(TAG, msg);
11124                     throw new IllegalArgumentException(msg);
11125                 }
11126                 if (conn == null) {
11127                     throw new NullPointerException("connection is null");
11128                 }
11129                 if (decProviderCountLocked(conn, null, null, stable)) {
11130                     updateOomAdjLocked();
11131                 }
11132             }
11133         } finally {
11134             Binder.restoreCallingIdentity(ident);
11135         }
11136     }
11137
11138     public void removeContentProviderExternal(String name, IBinder token) {
11139         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11140             "Do not have permission in call removeContentProviderExternal()");
11141         int userId = UserHandle.getCallingUserId();
11142         long ident = Binder.clearCallingIdentity();
11143         try {
11144             removeContentProviderExternalUnchecked(name, token, userId);
11145         } finally {
11146             Binder.restoreCallingIdentity(ident);
11147         }
11148     }
11149
11150     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11151         synchronized (this) {
11152             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11153             if(cpr == null) {
11154                 //remove from mProvidersByClass
11155                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11156                 return;
11157             }
11158
11159             //update content provider record entry info
11160             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11161             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11162             if (localCpr.hasExternalProcessHandles()) {
11163                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11164                     updateOomAdjLocked();
11165                 } else {
11166                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11167                             + " with no external reference for token: "
11168                             + token + ".");
11169                 }
11170             } else {
11171                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11172                         + " with no external references.");
11173             }
11174         }
11175     }
11176
11177     public final void publishContentProviders(IApplicationThread caller,
11178             List<ContentProviderHolder> providers) {
11179         if (providers == null) {
11180             return;
11181         }
11182
11183         enforceNotIsolatedCaller("publishContentProviders");
11184         synchronized (this) {
11185             final ProcessRecord r = getRecordForAppLocked(caller);
11186             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11187             if (r == null) {
11188                 throw new SecurityException(
11189                         "Unable to find app for caller " + caller
11190                       + " (pid=" + Binder.getCallingPid()
11191                       + ") when publishing content providers");
11192             }
11193
11194             final long origId = Binder.clearCallingIdentity();
11195
11196             final int N = providers.size();
11197             for (int i = 0; i < N; i++) {
11198                 ContentProviderHolder src = providers.get(i);
11199                 if (src == null || src.info == null || src.provider == null) {
11200                     continue;
11201                 }
11202                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11203                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11204                 if (dst != null) {
11205                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11206                     mProviderMap.putProviderByClass(comp, dst);
11207                     String names[] = dst.info.authority.split(";");
11208                     for (int j = 0; j < names.length; j++) {
11209                         mProviderMap.putProviderByName(names[j], dst);
11210                     }
11211
11212                     int launchingCount = mLaunchingProviders.size();
11213                     int j;
11214                     boolean wasInLaunchingProviders = false;
11215                     for (j = 0; j < launchingCount; j++) {
11216                         if (mLaunchingProviders.get(j) == dst) {
11217                             mLaunchingProviders.remove(j);
11218                             wasInLaunchingProviders = true;
11219                             j--;
11220                             launchingCount--;
11221                         }
11222                     }
11223                     if (wasInLaunchingProviders) {
11224                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11225                     }
11226                     synchronized (dst) {
11227                         dst.provider = src.provider;
11228                         dst.proc = r;
11229                         dst.notifyAll();
11230                     }
11231                     updateOomAdjLocked(r);
11232                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11233                             src.info.authority);
11234                 }
11235             }
11236
11237             Binder.restoreCallingIdentity(origId);
11238         }
11239     }
11240
11241     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11242         ContentProviderConnection conn;
11243         try {
11244             conn = (ContentProviderConnection)connection;
11245         } catch (ClassCastException e) {
11246             String msg ="refContentProvider: " + connection
11247                     + " not a ContentProviderConnection";
11248             Slog.w(TAG, msg);
11249             throw new IllegalArgumentException(msg);
11250         }
11251         if (conn == null) {
11252             throw new NullPointerException("connection is null");
11253         }
11254
11255         synchronized (this) {
11256             if (stable > 0) {
11257                 conn.numStableIncs += stable;
11258             }
11259             stable = conn.stableCount + stable;
11260             if (stable < 0) {
11261                 throw new IllegalStateException("stableCount < 0: " + stable);
11262             }
11263
11264             if (unstable > 0) {
11265                 conn.numUnstableIncs += unstable;
11266             }
11267             unstable = conn.unstableCount + unstable;
11268             if (unstable < 0) {
11269                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11270             }
11271
11272             if ((stable+unstable) <= 0) {
11273                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11274                         + stable + " unstable=" + unstable);
11275             }
11276             conn.stableCount = stable;
11277             conn.unstableCount = unstable;
11278             return !conn.dead;
11279         }
11280     }
11281
11282     public void unstableProviderDied(IBinder connection) {
11283         ContentProviderConnection conn;
11284         try {
11285             conn = (ContentProviderConnection)connection;
11286         } catch (ClassCastException e) {
11287             String msg ="refContentProvider: " + connection
11288                     + " not a ContentProviderConnection";
11289             Slog.w(TAG, msg);
11290             throw new IllegalArgumentException(msg);
11291         }
11292         if (conn == null) {
11293             throw new NullPointerException("connection is null");
11294         }
11295
11296         // Safely retrieve the content provider associated with the connection.
11297         IContentProvider provider;
11298         synchronized (this) {
11299             provider = conn.provider.provider;
11300         }
11301
11302         if (provider == null) {
11303             // Um, yeah, we're way ahead of you.
11304             return;
11305         }
11306
11307         // Make sure the caller is being honest with us.
11308         if (provider.asBinder().pingBinder()) {
11309             // Er, no, still looks good to us.
11310             synchronized (this) {
11311                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11312                         + " says " + conn + " died, but we don't agree");
11313                 return;
11314             }
11315         }
11316
11317         // Well look at that!  It's dead!
11318         synchronized (this) {
11319             if (conn.provider.provider != provider) {
11320                 // But something changed...  good enough.
11321                 return;
11322             }
11323
11324             ProcessRecord proc = conn.provider.proc;
11325             if (proc == null || proc.thread == null) {
11326                 // Seems like the process is already cleaned up.
11327                 return;
11328             }
11329
11330             // As far as we're concerned, this is just like receiving a
11331             // death notification...  just a bit prematurely.
11332             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11333                     + ") early provider death");
11334             final long ident = Binder.clearCallingIdentity();
11335             try {
11336                 appDiedLocked(proc);
11337             } finally {
11338                 Binder.restoreCallingIdentity(ident);
11339             }
11340         }
11341     }
11342
11343     @Override
11344     public void appNotRespondingViaProvider(IBinder connection) {
11345         enforceCallingPermission(
11346                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11347
11348         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11349         if (conn == null) {
11350             Slog.w(TAG, "ContentProviderConnection is null");
11351             return;
11352         }
11353
11354         final ProcessRecord host = conn.provider.proc;
11355         if (host == null) {
11356             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11357             return;
11358         }
11359
11360         mHandler.post(new Runnable() {
11361             @Override
11362             public void run() {
11363                 mAppErrors.appNotResponding(host, null, null, false,
11364                         "ContentProvider not responding");
11365             }
11366         });
11367     }
11368
11369     public final void installSystemProviders() {
11370         List<ProviderInfo> providers;
11371         synchronized (this) {
11372             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11373             providers = generateApplicationProvidersLocked(app);
11374             if (providers != null) {
11375                 for (int i=providers.size()-1; i>=0; i--) {
11376                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11377                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11378                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11379                                 + ": not system .apk");
11380                         providers.remove(i);
11381                     }
11382                 }
11383             }
11384         }
11385         if (providers != null) {
11386             mSystemThread.installSystemProviders(providers);
11387         }
11388
11389         mCoreSettingsObserver = new CoreSettingsObserver(this);
11390         mFontScaleSettingObserver = new FontScaleSettingObserver();
11391
11392         //mUsageStatsService.monitorPackages();
11393     }
11394
11395     private void startPersistentApps(int matchFlags) {
11396         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11397
11398         synchronized (this) {
11399             try {
11400                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11401                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11402                 for (ApplicationInfo app : apps) {
11403                     if (!"android".equals(app.packageName)) {
11404                         addAppLocked(app, false, null /* ABI override */);
11405                     }
11406                 }
11407             } catch (RemoteException ex) {
11408             }
11409         }
11410     }
11411
11412     /**
11413      * When a user is unlocked, we need to install encryption-unaware providers
11414      * belonging to any running apps.
11415      */
11416     private void installEncryptionUnawareProviders(int userId) {
11417         // We're only interested in providers that are encryption unaware, and
11418         // we don't care about uninstalled apps, since there's no way they're
11419         // running at this point.
11420         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11421
11422         synchronized (this) {
11423             final int NP = mProcessNames.getMap().size();
11424             for (int ip = 0; ip < NP; ip++) {
11425                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11426                 final int NA = apps.size();
11427                 for (int ia = 0; ia < NA; ia++) {
11428                     final ProcessRecord app = apps.valueAt(ia);
11429                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11430
11431                     final int NG = app.pkgList.size();
11432                     for (int ig = 0; ig < NG; ig++) {
11433                         try {
11434                             final String pkgName = app.pkgList.keyAt(ig);
11435                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11436                                     .getPackageInfo(pkgName, matchFlags, userId);
11437                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11438                                 for (ProviderInfo pi : pkgInfo.providers) {
11439                                     // TODO: keep in sync with generateApplicationProvidersLocked
11440                                     final boolean processMatch = Objects.equals(pi.processName,
11441                                             app.processName) || pi.multiprocess;
11442                                     final boolean userMatch = isSingleton(pi.processName,
11443                                             pi.applicationInfo, pi.name, pi.flags)
11444                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11445                                     if (processMatch && userMatch) {
11446                                         Log.v(TAG, "Installing " + pi);
11447                                         app.thread.scheduleInstallProvider(pi);
11448                                     } else {
11449                                         Log.v(TAG, "Skipping " + pi);
11450                                     }
11451                                 }
11452                             }
11453                         } catch (RemoteException ignored) {
11454                         }
11455                     }
11456                 }
11457             }
11458         }
11459     }
11460
11461     /**
11462      * Allows apps to retrieve the MIME type of a URI.
11463      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11464      * users, then it does not need permission to access the ContentProvider.
11465      * Either, it needs cross-user uri grants.
11466      *
11467      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11468      *
11469      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11470      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11471      */
11472     public String getProviderMimeType(Uri uri, int userId) {
11473         enforceNotIsolatedCaller("getProviderMimeType");
11474         final String name = uri.getAuthority();
11475         int callingUid = Binder.getCallingUid();
11476         int callingPid = Binder.getCallingPid();
11477         long ident = 0;
11478         boolean clearedIdentity = false;
11479         synchronized (this) {
11480             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11481         }
11482         if (canClearIdentity(callingPid, callingUid, userId)) {
11483             clearedIdentity = true;
11484             ident = Binder.clearCallingIdentity();
11485         }
11486         ContentProviderHolder holder = null;
11487         try {
11488             holder = getContentProviderExternalUnchecked(name, null, userId);
11489             if (holder != null) {
11490                 return holder.provider.getType(uri);
11491             }
11492         } catch (RemoteException e) {
11493             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11494             return null;
11495         } catch (Exception e) {
11496             Log.w(TAG, "Exception while determining type of " + uri, e);
11497             return null;
11498         } finally {
11499             // We need to clear the identity to call removeContentProviderExternalUnchecked
11500             if (!clearedIdentity) {
11501                 ident = Binder.clearCallingIdentity();
11502             }
11503             try {
11504                 if (holder != null) {
11505                     removeContentProviderExternalUnchecked(name, null, userId);
11506                 }
11507             } finally {
11508                 Binder.restoreCallingIdentity(ident);
11509             }
11510         }
11511
11512         return null;
11513     }
11514
11515     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11516         if (UserHandle.getUserId(callingUid) == userId) {
11517             return true;
11518         }
11519         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11520                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11521                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11522                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11523                 return true;
11524         }
11525         return false;
11526     }
11527
11528     // =========================================================
11529     // GLOBAL MANAGEMENT
11530     // =========================================================
11531
11532     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11533             boolean isolated, int isolatedUid) {
11534         String proc = customProcess != null ? customProcess : info.processName;
11535         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11536         final int userId = UserHandle.getUserId(info.uid);
11537         int uid = info.uid;
11538         if (isolated) {
11539             if (isolatedUid == 0) {
11540                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11541                 while (true) {
11542                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11543                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11544                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11545                     }
11546                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11547                     mNextIsolatedProcessUid++;
11548                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11549                         // No process for this uid, use it.
11550                         break;
11551                     }
11552                     stepsLeft--;
11553                     if (stepsLeft <= 0) {
11554                         return null;
11555                     }
11556                 }
11557             } else {
11558                 // Special case for startIsolatedProcess (internal only), where
11559                 // the uid of the isolated process is specified by the caller.
11560                 uid = isolatedUid;
11561             }
11562
11563             // Register the isolated UID with this application so BatteryStats knows to
11564             // attribute resource usage to the application.
11565             //
11566             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11567             // about the process state of the isolated UID *before* it is registered with the
11568             // owning application.
11569             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11570         }
11571         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11572         if (!mBooted && !mBooting
11573                 && userId == UserHandle.USER_SYSTEM
11574                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11575             r.persistent = true;
11576         }
11577         addProcessNameLocked(r);
11578         return r;
11579     }
11580
11581     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11582             String abiOverride) {
11583         ProcessRecord app;
11584         if (!isolated) {
11585             app = getProcessRecordLocked(info.processName, info.uid, true);
11586         } else {
11587             app = null;
11588         }
11589
11590         if (app == null) {
11591             app = newProcessRecordLocked(info, null, isolated, 0);
11592             updateLruProcessLocked(app, false, null);
11593             updateOomAdjLocked();
11594         }
11595
11596         // This package really, really can not be stopped.
11597         try {
11598             AppGlobals.getPackageManager().setPackageStoppedState(
11599                     info.packageName, false, UserHandle.getUserId(app.uid));
11600         } catch (RemoteException e) {
11601         } catch (IllegalArgumentException e) {
11602             Slog.w(TAG, "Failed trying to unstop package "
11603                     + info.packageName + ": " + e);
11604         }
11605
11606         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11607             app.persistent = true;
11608             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11609         }
11610         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11611             mPersistentStartingProcesses.add(app);
11612             startProcessLocked(app, "added application", app.processName, abiOverride,
11613                     null /* entryPoint */, null /* entryPointArgs */);
11614         }
11615
11616         return app;
11617     }
11618
11619     public void unhandledBack() {
11620         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11621                 "unhandledBack()");
11622
11623         synchronized(this) {
11624             final long origId = Binder.clearCallingIdentity();
11625             try {
11626                 getFocusedStack().unhandledBackLocked();
11627             } finally {
11628                 Binder.restoreCallingIdentity(origId);
11629             }
11630         }
11631     }
11632
11633     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11634         enforceNotIsolatedCaller("openContentUri");
11635         final int userId = UserHandle.getCallingUserId();
11636         String name = uri.getAuthority();
11637         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11638         ParcelFileDescriptor pfd = null;
11639         if (cph != null) {
11640             // We record the binder invoker's uid in thread-local storage before
11641             // going to the content provider to open the file.  Later, in the code
11642             // that handles all permissions checks, we look for this uid and use
11643             // that rather than the Activity Manager's own uid.  The effect is that
11644             // we do the check against the caller's permissions even though it looks
11645             // to the content provider like the Activity Manager itself is making
11646             // the request.
11647             Binder token = new Binder();
11648             sCallerIdentity.set(new Identity(
11649                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11650             try {
11651                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11652             } catch (FileNotFoundException e) {
11653                 // do nothing; pfd will be returned null
11654             } finally {
11655                 // Ensure that whatever happens, we clean up the identity state
11656                 sCallerIdentity.remove();
11657                 // Ensure we're done with the provider.
11658                 removeContentProviderExternalUnchecked(name, null, userId);
11659             }
11660         } else {
11661             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11662         }
11663         return pfd;
11664     }
11665
11666     // Actually is sleeping or shutting down or whatever else in the future
11667     // is an inactive state.
11668     boolean isSleepingOrShuttingDownLocked() {
11669         return isSleepingLocked() || mShuttingDown;
11670     }
11671
11672     boolean isShuttingDownLocked() {
11673         return mShuttingDown;
11674     }
11675
11676     boolean isSleepingLocked() {
11677         return mSleeping;
11678     }
11679
11680     void onWakefulnessChanged(int wakefulness) {
11681         synchronized(this) {
11682             mWakefulness = wakefulness;
11683             updateSleepIfNeededLocked();
11684         }
11685     }
11686
11687     void finishRunningVoiceLocked() {
11688         if (mRunningVoice != null) {
11689             mRunningVoice = null;
11690             mVoiceWakeLock.release();
11691             updateSleepIfNeededLocked();
11692         }
11693     }
11694
11695     void startTimeTrackingFocusedActivityLocked() {
11696         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11697             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11698         }
11699     }
11700
11701     void updateSleepIfNeededLocked() {
11702         if (mSleeping && !shouldSleepLocked()) {
11703             mSleeping = false;
11704             startTimeTrackingFocusedActivityLocked();
11705             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11706             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11707             updateOomAdjLocked();
11708         } else if (!mSleeping && shouldSleepLocked()) {
11709             mSleeping = true;
11710             if (mCurAppTimeTracker != null) {
11711                 mCurAppTimeTracker.stop();
11712             }
11713             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11714             mStackSupervisor.goingToSleepLocked();
11715             updateOomAdjLocked();
11716
11717             // Initialize the wake times of all processes.
11718             checkExcessivePowerUsageLocked(false);
11719             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11720             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11721             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11722         }
11723     }
11724
11725     private boolean shouldSleepLocked() {
11726         // Resume applications while running a voice interactor.
11727         if (mRunningVoice != null) {
11728             return false;
11729         }
11730
11731         // TODO: Transform the lock screen state into a sleep token instead.
11732         switch (mWakefulness) {
11733             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11734             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11735             case PowerManagerInternal.WAKEFULNESS_DOZING:
11736                 // Pause applications whenever the lock screen is shown or any sleep
11737                 // tokens have been acquired.
11738                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11739             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11740             default:
11741                 // If we're asleep then pause applications unconditionally.
11742                 return true;
11743         }
11744     }
11745
11746     /** Pokes the task persister. */
11747     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11748         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11749     }
11750
11751     /** Notifies all listeners when the task stack has changed. */
11752     void notifyTaskStackChangedLocked() {
11753         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11754         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11755         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11756         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11757     }
11758
11759     /** Notifies all listeners when an Activity is pinned. */
11760     void notifyActivityPinnedLocked() {
11761         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11762         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11763     }
11764
11765     /**
11766      * Notifies all listeners when an attempt was made to start an an activity that is already
11767      * running in the pinned stack and the activity was not actually started, but the task is
11768      * either brought to the front or a new Intent is delivered to it.
11769      */
11770     void notifyPinnedActivityRestartAttemptLocked() {
11771         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11772         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11773     }
11774
11775     /** Notifies all listeners when the pinned stack animation ends. */
11776     @Override
11777     public void notifyPinnedStackAnimationEnded() {
11778         synchronized (this) {
11779             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11780             mHandler.obtainMessage(
11781                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11782         }
11783     }
11784
11785     @Override
11786     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11787         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11788     }
11789
11790     @Override
11791     public boolean shutdown(int timeout) {
11792         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11793                 != PackageManager.PERMISSION_GRANTED) {
11794             throw new SecurityException("Requires permission "
11795                     + android.Manifest.permission.SHUTDOWN);
11796         }
11797
11798         boolean timedout = false;
11799
11800         synchronized(this) {
11801             mShuttingDown = true;
11802             updateEventDispatchingLocked();
11803             timedout = mStackSupervisor.shutdownLocked(timeout);
11804         }
11805
11806         mAppOpsService.shutdown();
11807         if (mUsageStatsService != null) {
11808             mUsageStatsService.prepareShutdown();
11809         }
11810         mBatteryStatsService.shutdown();
11811         synchronized (this) {
11812             mProcessStats.shutdownLocked();
11813             notifyTaskPersisterLocked(null, true);
11814         }
11815
11816         return timedout;
11817     }
11818
11819     public final void activitySlept(IBinder token) {
11820         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11821
11822         final long origId = Binder.clearCallingIdentity();
11823
11824         synchronized (this) {
11825             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11826             if (r != null) {
11827                 mStackSupervisor.activitySleptLocked(r);
11828             }
11829         }
11830
11831         Binder.restoreCallingIdentity(origId);
11832     }
11833
11834     private String lockScreenShownToString() {
11835         switch (mLockScreenShown) {
11836             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11837             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11838             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11839             default: return "Unknown=" + mLockScreenShown;
11840         }
11841     }
11842
11843     void logLockScreen(String msg) {
11844         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11845                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11846                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11847                 + " mSleeping=" + mSleeping);
11848     }
11849
11850     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11851         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11852         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11853         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11854             boolean wasRunningVoice = mRunningVoice != null;
11855             mRunningVoice = session;
11856             if (!wasRunningVoice) {
11857                 mVoiceWakeLock.acquire();
11858                 updateSleepIfNeededLocked();
11859             }
11860         }
11861     }
11862
11863     private void updateEventDispatchingLocked() {
11864         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11865     }
11866
11867     public void setLockScreenShown(boolean showing, boolean occluded) {
11868         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11869                 != PackageManager.PERMISSION_GRANTED) {
11870             throw new SecurityException("Requires permission "
11871                     + android.Manifest.permission.DEVICE_POWER);
11872         }
11873
11874         synchronized(this) {
11875             long ident = Binder.clearCallingIdentity();
11876             try {
11877                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11878                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11879                 if (showing && occluded) {
11880                     // The lock screen is currently showing, but is occluded by a window that can
11881                     // show on top of the lock screen. In this can we want to dismiss the docked
11882                     // stack since it will be complicated/risky to try to put the activity on top
11883                     // of the lock screen in the right fullscreen configuration.
11884                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11885                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11886                 }
11887
11888                 updateSleepIfNeededLocked();
11889             } finally {
11890                 Binder.restoreCallingIdentity(ident);
11891             }
11892         }
11893     }
11894
11895     @Override
11896     public void notifyLockedProfile(@UserIdInt int userId) {
11897         try {
11898             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11899                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11900             }
11901         } catch (RemoteException ex) {
11902             throw new SecurityException("Fail to check is caller a privileged app", ex);
11903         }
11904
11905         synchronized (this) {
11906             if (mStackSupervisor.isUserLockedProfile(userId)) {
11907                 final long ident = Binder.clearCallingIdentity();
11908                 try {
11909                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11910
11911                     // Drop locked freeform tasks out into the fullscreen stack.
11912                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11913                     //       where they were before, but in an obscured state.
11914                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11915
11916                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11917                         // If there is no device lock, we will show the profile's credential page.
11918                         mActivityStarter.showConfirmDeviceCredential(userId);
11919                     } else {
11920                         // Showing launcher to avoid user entering credential twice.
11921                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11922                     }
11923                 } finally {
11924                     Binder.restoreCallingIdentity(ident);
11925                 }
11926             }
11927         }
11928     }
11929
11930     @Override
11931     public void startConfirmDeviceCredentialIntent(Intent intent) {
11932         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11933         synchronized (this) {
11934             final long ident = Binder.clearCallingIdentity();
11935             try {
11936                 mActivityStarter.startConfirmCredentialIntent(intent);
11937             } finally {
11938                 Binder.restoreCallingIdentity(ident);
11939             }
11940         }
11941     }
11942
11943     @Override
11944     public void stopAppSwitches() {
11945         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11946                 != PackageManager.PERMISSION_GRANTED) {
11947             throw new SecurityException("viewquires permission "
11948                     + android.Manifest.permission.STOP_APP_SWITCHES);
11949         }
11950
11951         synchronized(this) {
11952             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11953                     + APP_SWITCH_DELAY_TIME;
11954             mDidAppSwitch = false;
11955             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11956             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11957             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11958         }
11959     }
11960
11961     public void resumeAppSwitches() {
11962         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11963                 != PackageManager.PERMISSION_GRANTED) {
11964             throw new SecurityException("Requires permission "
11965                     + android.Manifest.permission.STOP_APP_SWITCHES);
11966         }
11967
11968         synchronized(this) {
11969             // Note that we don't execute any pending app switches... we will
11970             // let those wait until either the timeout, or the next start
11971             // activity request.
11972             mAppSwitchesAllowedTime = 0;
11973         }
11974     }
11975
11976     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11977             int callingPid, int callingUid, String name) {
11978         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11979             return true;
11980         }
11981
11982         int perm = checkComponentPermission(
11983                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11984                 sourceUid, -1, true);
11985         if (perm == PackageManager.PERMISSION_GRANTED) {
11986             return true;
11987         }
11988
11989         // If the actual IPC caller is different from the logical source, then
11990         // also see if they are allowed to control app switches.
11991         if (callingUid != -1 && callingUid != sourceUid) {
11992             perm = checkComponentPermission(
11993                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11994                     callingUid, -1, true);
11995             if (perm == PackageManager.PERMISSION_GRANTED) {
11996                 return true;
11997             }
11998         }
11999
12000         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12001         return false;
12002     }
12003
12004     public void setDebugApp(String packageName, boolean waitForDebugger,
12005             boolean persistent) {
12006         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12007                 "setDebugApp()");
12008
12009         long ident = Binder.clearCallingIdentity();
12010         try {
12011             // Note that this is not really thread safe if there are multiple
12012             // callers into it at the same time, but that's not a situation we
12013             // care about.
12014             if (persistent) {
12015                 final ContentResolver resolver = mContext.getContentResolver();
12016                 Settings.Global.putString(
12017                     resolver, Settings.Global.DEBUG_APP,
12018                     packageName);
12019                 Settings.Global.putInt(
12020                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12021                     waitForDebugger ? 1 : 0);
12022             }
12023
12024             synchronized (this) {
12025                 if (!persistent) {
12026                     mOrigDebugApp = mDebugApp;
12027                     mOrigWaitForDebugger = mWaitForDebugger;
12028                 }
12029                 mDebugApp = packageName;
12030                 mWaitForDebugger = waitForDebugger;
12031                 mDebugTransient = !persistent;
12032                 if (packageName != null) {
12033                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12034                             false, UserHandle.USER_ALL, "set debug app");
12035                 }
12036             }
12037         } finally {
12038             Binder.restoreCallingIdentity(ident);
12039         }
12040     }
12041
12042     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12043         synchronized (this) {
12044             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12045             if (!isDebuggable) {
12046                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12047                     throw new SecurityException("Process not debuggable: " + app.packageName);
12048                 }
12049             }
12050
12051             mTrackAllocationApp = processName;
12052         }
12053     }
12054
12055     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12056         synchronized (this) {
12057             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12058             if (!isDebuggable) {
12059                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12060                     throw new SecurityException("Process not debuggable: " + app.packageName);
12061                 }
12062             }
12063             mProfileApp = processName;
12064             mProfileFile = profilerInfo.profileFile;
12065             if (mProfileFd != null) {
12066                 try {
12067                     mProfileFd.close();
12068                 } catch (IOException e) {
12069                 }
12070                 mProfileFd = null;
12071             }
12072             mProfileFd = profilerInfo.profileFd;
12073             mSamplingInterval = profilerInfo.samplingInterval;
12074             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12075             mProfileType = 0;
12076         }
12077     }
12078
12079     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12080         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12081         if (!isDebuggable) {
12082             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12083                 throw new SecurityException("Process not debuggable: " + app.packageName);
12084             }
12085         }
12086         mNativeDebuggingApp = processName;
12087     }
12088
12089     @Override
12090     public void setAlwaysFinish(boolean enabled) {
12091         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12092                 "setAlwaysFinish()");
12093
12094         long ident = Binder.clearCallingIdentity();
12095         try {
12096             Settings.Global.putInt(
12097                     mContext.getContentResolver(),
12098                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12099
12100             synchronized (this) {
12101                 mAlwaysFinishActivities = enabled;
12102             }
12103         } finally {
12104             Binder.restoreCallingIdentity(ident);
12105         }
12106     }
12107
12108     @Override
12109     public void setLenientBackgroundCheck(boolean enabled) {
12110         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12111                 "setLenientBackgroundCheck()");
12112
12113         long ident = Binder.clearCallingIdentity();
12114         try {
12115             Settings.Global.putInt(
12116                     mContext.getContentResolver(),
12117                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12118
12119             synchronized (this) {
12120                 mLenientBackgroundCheck = enabled;
12121             }
12122         } finally {
12123             Binder.restoreCallingIdentity(ident);
12124         }
12125     }
12126
12127     @Override
12128     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12129         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12130                 "setActivityController()");
12131         synchronized (this) {
12132             mController = controller;
12133             mControllerIsAMonkey = imAMonkey;
12134             Watchdog.getInstance().setActivityController(controller);
12135         }
12136     }
12137
12138     @Override
12139     public void setUserIsMonkey(boolean userIsMonkey) {
12140         synchronized (this) {
12141             synchronized (mPidsSelfLocked) {
12142                 final int callingPid = Binder.getCallingPid();
12143                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12144                 if (precessRecord == null) {
12145                     throw new SecurityException("Unknown process: " + callingPid);
12146                 }
12147                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12148                     throw new SecurityException("Only an instrumentation process "
12149                             + "with a UiAutomation can call setUserIsMonkey");
12150                 }
12151             }
12152             mUserIsMonkey = userIsMonkey;
12153         }
12154     }
12155
12156     @Override
12157     public boolean isUserAMonkey() {
12158         synchronized (this) {
12159             // If there is a controller also implies the user is a monkey.
12160             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12161         }
12162     }
12163
12164     public void requestBugReport(int bugreportType) {
12165         String service = null;
12166         switch (bugreportType) {
12167             case ActivityManager.BUGREPORT_OPTION_FULL:
12168                 service = "bugreport";
12169                 break;
12170             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12171                 service = "bugreportplus";
12172                 break;
12173             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12174                 service = "bugreportremote";
12175                 break;
12176             case ActivityManager.BUGREPORT_OPTION_WEAR:
12177                 service = "bugreportwear";
12178                 break;
12179         }
12180         if (service == null) {
12181             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12182                     + bugreportType);
12183         }
12184         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12185         SystemProperties.set("ctl.start", service);
12186     }
12187
12188     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12189         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12190     }
12191
12192     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12193         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12194             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12195         }
12196         return KEY_DISPATCHING_TIMEOUT;
12197     }
12198
12199     @Override
12200     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12201         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12202                 != PackageManager.PERMISSION_GRANTED) {
12203             throw new SecurityException("Requires permission "
12204                     + android.Manifest.permission.FILTER_EVENTS);
12205         }
12206         ProcessRecord proc;
12207         long timeout;
12208         synchronized (this) {
12209             synchronized (mPidsSelfLocked) {
12210                 proc = mPidsSelfLocked.get(pid);
12211             }
12212             timeout = getInputDispatchingTimeoutLocked(proc);
12213         }
12214
12215         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12216             return -1;
12217         }
12218
12219         return timeout;
12220     }
12221
12222     /**
12223      * Handle input dispatching timeouts.
12224      * Returns whether input dispatching should be aborted or not.
12225      */
12226     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12227             final ActivityRecord activity, final ActivityRecord parent,
12228             final boolean aboveSystem, String reason) {
12229         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12230                 != PackageManager.PERMISSION_GRANTED) {
12231             throw new SecurityException("Requires permission "
12232                     + android.Manifest.permission.FILTER_EVENTS);
12233         }
12234
12235         final String annotation;
12236         if (reason == null) {
12237             annotation = "Input dispatching timed out";
12238         } else {
12239             annotation = "Input dispatching timed out (" + reason + ")";
12240         }
12241
12242         if (proc != null) {
12243             synchronized (this) {
12244                 if (proc.debugging) {
12245                     return false;
12246                 }
12247
12248                 if (mDidDexOpt) {
12249                     // Give more time since we were dexopting.
12250                     mDidDexOpt = false;
12251                     return false;
12252                 }
12253
12254                 if (proc.instrumentationClass != null) {
12255                     Bundle info = new Bundle();
12256                     info.putString("shortMsg", "keyDispatchingTimedOut");
12257                     info.putString("longMsg", annotation);
12258                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12259                     return true;
12260                 }
12261             }
12262             mHandler.post(new Runnable() {
12263                 @Override
12264                 public void run() {
12265                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12266                 }
12267             });
12268         }
12269
12270         return true;
12271     }
12272
12273     @Override
12274     public Bundle getAssistContextExtras(int requestType) {
12275         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12276                 null, null, true /* focused */, true /* newSessionId */,
12277                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12278         if (pae == null) {
12279             return null;
12280         }
12281         synchronized (pae) {
12282             while (!pae.haveResult) {
12283                 try {
12284                     pae.wait();
12285                 } catch (InterruptedException e) {
12286                 }
12287             }
12288         }
12289         synchronized (this) {
12290             buildAssistBundleLocked(pae, pae.result);
12291             mPendingAssistExtras.remove(pae);
12292             mUiHandler.removeCallbacks(pae);
12293         }
12294         return pae.extras;
12295     }
12296
12297     @Override
12298     public boolean isAssistDataAllowedOnCurrentActivity() {
12299         int userId;
12300         synchronized (this) {
12301             userId = mUserController.getCurrentUserIdLocked();
12302             ActivityRecord activity = getFocusedStack().topActivity();
12303             if (activity == null) {
12304                 return false;
12305             }
12306             userId = activity.userId;
12307         }
12308         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12309                 Context.DEVICE_POLICY_SERVICE);
12310         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12311     }
12312
12313     @Override
12314     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12315         long ident = Binder.clearCallingIdentity();
12316         try {
12317             synchronized (this) {
12318                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12319                 ActivityRecord top = getFocusedStack().topActivity();
12320                 if (top != caller) {
12321                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12322                             + " is not current top " + top);
12323                     return false;
12324                 }
12325                 if (!top.nowVisible) {
12326                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12327                             + " is not visible");
12328                     return false;
12329                 }
12330             }
12331             AssistUtils utils = new AssistUtils(mContext);
12332             return utils.showSessionForActiveService(args,
12333                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12334         } finally {
12335             Binder.restoreCallingIdentity(ident);
12336         }
12337     }
12338
12339     @Override
12340     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12341             Bundle receiverExtras,
12342             IBinder activityToken, boolean focused, boolean newSessionId) {
12343         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12344                 activityToken, focused, newSessionId,
12345                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12346                 != null;
12347     }
12348
12349     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12350             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12351             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12352         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12353                 "enqueueAssistContext()");
12354         synchronized (this) {
12355             ActivityRecord activity = getFocusedStack().topActivity();
12356             if (activity == null) {
12357                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12358                 return null;
12359             }
12360             if (activity.app == null || activity.app.thread == null) {
12361                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12362                 return null;
12363             }
12364             if (focused) {
12365                 if (activityToken != null) {
12366                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12367                     if (activity != caller) {
12368                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12369                                 + " is not current top " + activity);
12370                         return null;
12371                     }
12372                 }
12373             } else {
12374                 activity = ActivityRecord.forTokenLocked(activityToken);
12375                 if (activity == null) {
12376                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12377                             + " couldn't be found");
12378                     return null;
12379                 }
12380             }
12381
12382             PendingAssistExtras pae;
12383             Bundle extras = new Bundle();
12384             if (args != null) {
12385                 extras.putAll(args);
12386             }
12387             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12388             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12389             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12390                     userHandle);
12391             // Increment the sessionId if necessary
12392             if (newSessionId) {
12393                 mViSessionId++;
12394             }
12395             try {
12396                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12397                         requestType, mViSessionId);
12398                 mPendingAssistExtras.add(pae);
12399                 mUiHandler.postDelayed(pae, timeout);
12400             } catch (RemoteException e) {
12401                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12402                 return null;
12403             }
12404             return pae;
12405         }
12406     }
12407
12408     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12409         IResultReceiver receiver;
12410         synchronized (this) {
12411             mPendingAssistExtras.remove(pae);
12412             receiver = pae.receiver;
12413         }
12414         if (receiver != null) {
12415             // Caller wants result sent back to them.
12416             Bundle sendBundle = new Bundle();
12417             // At least return the receiver extras
12418             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12419                     pae.receiverExtras);
12420             try {
12421                 pae.receiver.send(0, sendBundle);
12422             } catch (RemoteException e) {
12423             }
12424         }
12425     }
12426
12427     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12428         if (result != null) {
12429             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12430         }
12431         if (pae.hint != null) {
12432             pae.extras.putBoolean(pae.hint, true);
12433         }
12434     }
12435
12436     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12437             AssistContent content, Uri referrer) {
12438         PendingAssistExtras pae = (PendingAssistExtras)token;
12439         synchronized (pae) {
12440             pae.result = extras;
12441             pae.structure = structure;
12442             pae.content = content;
12443             if (referrer != null) {
12444                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12445             }
12446             pae.haveResult = true;
12447             pae.notifyAll();
12448             if (pae.intent == null && pae.receiver == null) {
12449                 // Caller is just waiting for the result.
12450                 return;
12451             }
12452         }
12453
12454         // We are now ready to launch the assist activity.
12455         IResultReceiver sendReceiver = null;
12456         Bundle sendBundle = null;
12457         synchronized (this) {
12458             buildAssistBundleLocked(pae, extras);
12459             boolean exists = mPendingAssistExtras.remove(pae);
12460             mUiHandler.removeCallbacks(pae);
12461             if (!exists) {
12462                 // Timed out.
12463                 return;
12464             }
12465             if ((sendReceiver=pae.receiver) != null) {
12466                 // Caller wants result sent back to them.
12467                 sendBundle = new Bundle();
12468                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12469                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12470                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12471                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12472                         pae.receiverExtras);
12473             }
12474         }
12475         if (sendReceiver != null) {
12476             try {
12477                 sendReceiver.send(0, sendBundle);
12478             } catch (RemoteException e) {
12479             }
12480             return;
12481         }
12482
12483         long ident = Binder.clearCallingIdentity();
12484         try {
12485             pae.intent.replaceExtras(pae.extras);
12486             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12487                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12488                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12489             closeSystemDialogs("assist");
12490             try {
12491                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12492             } catch (ActivityNotFoundException e) {
12493                 Slog.w(TAG, "No activity to handle assist action.", e);
12494             }
12495         } finally {
12496             Binder.restoreCallingIdentity(ident);
12497         }
12498     }
12499
12500     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12501             Bundle args) {
12502         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12503                 true /* focused */, true /* newSessionId */,
12504                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12505     }
12506
12507     public void registerProcessObserver(IProcessObserver observer) {
12508         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12509                 "registerProcessObserver()");
12510         synchronized (this) {
12511             mProcessObservers.register(observer);
12512         }
12513     }
12514
12515     @Override
12516     public void unregisterProcessObserver(IProcessObserver observer) {
12517         synchronized (this) {
12518             mProcessObservers.unregister(observer);
12519         }
12520     }
12521
12522     @Override
12523     public void registerUidObserver(IUidObserver observer, int which) {
12524         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12525                 "registerUidObserver()");
12526         synchronized (this) {
12527             mUidObservers.register(observer, which);
12528         }
12529     }
12530
12531     @Override
12532     public void unregisterUidObserver(IUidObserver observer) {
12533         synchronized (this) {
12534             mUidObservers.unregister(observer);
12535         }
12536     }
12537
12538     @Override
12539     public boolean convertFromTranslucent(IBinder token) {
12540         final long origId = Binder.clearCallingIdentity();
12541         try {
12542             synchronized (this) {
12543                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12544                 if (r == null) {
12545                     return false;
12546                 }
12547                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12548                 if (translucentChanged) {
12549                     r.task.stack.releaseBackgroundResources(r);
12550                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12551                 }
12552                 mWindowManager.setAppFullscreen(token, true);
12553                 return translucentChanged;
12554             }
12555         } finally {
12556             Binder.restoreCallingIdentity(origId);
12557         }
12558     }
12559
12560     @Override
12561     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12562         final long origId = Binder.clearCallingIdentity();
12563         try {
12564             synchronized (this) {
12565                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12566                 if (r == null) {
12567                     return false;
12568                 }
12569                 int index = r.task.mActivities.lastIndexOf(r);
12570                 if (index > 0) {
12571                     ActivityRecord under = r.task.mActivities.get(index - 1);
12572                     under.returningOptions = options;
12573                 }
12574                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12575                 if (translucentChanged) {
12576                     r.task.stack.convertActivityToTranslucent(r);
12577                 }
12578                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12579                 mWindowManager.setAppFullscreen(token, false);
12580                 return translucentChanged;
12581             }
12582         } finally {
12583             Binder.restoreCallingIdentity(origId);
12584         }
12585     }
12586
12587     @Override
12588     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12589         final long origId = Binder.clearCallingIdentity();
12590         try {
12591             synchronized (this) {
12592                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12593                 if (r != null) {
12594                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12595                 }
12596             }
12597             return false;
12598         } finally {
12599             Binder.restoreCallingIdentity(origId);
12600         }
12601     }
12602
12603     @Override
12604     public boolean isBackgroundVisibleBehind(IBinder token) {
12605         final long origId = Binder.clearCallingIdentity();
12606         try {
12607             synchronized (this) {
12608                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12609                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12610                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12611                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12612                 return visible;
12613             }
12614         } finally {
12615             Binder.restoreCallingIdentity(origId);
12616         }
12617     }
12618
12619     @Override
12620     public ActivityOptions getActivityOptions(IBinder token) {
12621         final long origId = Binder.clearCallingIdentity();
12622         try {
12623             synchronized (this) {
12624                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12625                 if (r != null) {
12626                     final ActivityOptions activityOptions = r.pendingOptions;
12627                     r.pendingOptions = null;
12628                     return activityOptions;
12629                 }
12630                 return null;
12631             }
12632         } finally {
12633             Binder.restoreCallingIdentity(origId);
12634         }
12635     }
12636
12637     @Override
12638     public void setImmersive(IBinder token, boolean immersive) {
12639         synchronized(this) {
12640             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12641             if (r == null) {
12642                 throw new IllegalArgumentException();
12643             }
12644             r.immersive = immersive;
12645
12646             // update associated state if we're frontmost
12647             if (r == mFocusedActivity) {
12648                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12649                 applyUpdateLockStateLocked(r);
12650             }
12651         }
12652     }
12653
12654     @Override
12655     public boolean isImmersive(IBinder token) {
12656         synchronized (this) {
12657             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12658             if (r == null) {
12659                 throw new IllegalArgumentException();
12660             }
12661             return r.immersive;
12662         }
12663     }
12664
12665     public void setVrThread(int tid) {
12666         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12667             throw new UnsupportedOperationException("VR mode not supported on this device!");
12668         }
12669
12670         synchronized (this) {
12671             ProcessRecord proc;
12672             synchronized (mPidsSelfLocked) {
12673                 final int pid = Binder.getCallingPid();
12674                 proc = mPidsSelfLocked.get(pid);
12675
12676                 if (proc != null && mInVrMode && tid >= 0) {
12677                     // ensure the tid belongs to the process
12678                     if (!Process.isThreadInProcess(pid, tid)) {
12679                         throw new IllegalArgumentException("VR thread does not belong to process");
12680                     }
12681
12682                     // reset existing VR thread to CFS if this thread still exists and belongs to
12683                     // the calling process
12684                     if (proc.vrThreadTid != 0
12685                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12686                         try {
12687                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12688                         } catch (IllegalArgumentException e) {
12689                             // Ignore this.  Only occurs in race condition where previous VR thread
12690                             // was destroyed during this method call.
12691                         }
12692                     }
12693
12694                     proc.vrThreadTid = tid;
12695
12696                     // promote to FIFO now if the tid is non-zero
12697                     try {
12698                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12699                             proc.vrThreadTid > 0) {
12700                             Process.setThreadScheduler(proc.vrThreadTid,
12701                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12702                         }
12703                     } catch (IllegalArgumentException e) {
12704                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12705                                + " not exist:\n" + e);
12706                     }
12707                 }
12708             }
12709         }
12710     }
12711
12712     @Override
12713     public void setRenderThread(int tid) {
12714         synchronized (this) {
12715             ProcessRecord proc;
12716             synchronized (mPidsSelfLocked) {
12717                 int pid = Binder.getCallingPid();
12718                 proc = mPidsSelfLocked.get(pid);
12719                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12720                     // ensure the tid belongs to the process
12721                     if (!Process.isThreadInProcess(pid, tid)) {
12722                         throw new IllegalArgumentException(
12723                             "Render thread does not belong to process");
12724                     }
12725                     proc.renderThreadTid = tid;
12726                     if (DEBUG_OOM_ADJ) {
12727                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12728                     }
12729                     // promote to FIFO now
12730                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12731                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12732                         if (mUseFifoUiScheduling) {
12733                             Process.setThreadScheduler(proc.renderThreadTid,
12734                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12735                         } else {
12736                             Process.setThreadPriority(proc.renderThreadTid, -10);
12737                         }
12738                     }
12739                 } else {
12740                     if (DEBUG_OOM_ADJ) {
12741                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12742                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12743                                mUseFifoUiScheduling);
12744                     }
12745                 }
12746             }
12747         }
12748     }
12749
12750     @Override
12751     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12752         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12753             throw new UnsupportedOperationException("VR mode not supported on this device!");
12754         }
12755
12756         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12757
12758         ActivityRecord r;
12759         synchronized (this) {
12760             r = ActivityRecord.isInStackLocked(token);
12761         }
12762
12763         if (r == null) {
12764             throw new IllegalArgumentException();
12765         }
12766
12767         int err;
12768         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12769                 VrManagerInternal.NO_ERROR) {
12770             return err;
12771         }
12772
12773         synchronized(this) {
12774             r.requestedVrComponent = (enabled) ? packageName : null;
12775
12776             // Update associated state if this activity is currently focused
12777             if (r == mFocusedActivity) {
12778                 applyUpdateVrModeLocked(r);
12779             }
12780             return 0;
12781         }
12782     }
12783
12784     @Override
12785     public boolean isVrModePackageEnabled(ComponentName packageName) {
12786         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12787             throw new UnsupportedOperationException("VR mode not supported on this device!");
12788         }
12789
12790         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12791
12792         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12793                 VrManagerInternal.NO_ERROR;
12794     }
12795
12796     public boolean isTopActivityImmersive() {
12797         enforceNotIsolatedCaller("startActivity");
12798         synchronized (this) {
12799             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12800             return (r != null) ? r.immersive : false;
12801         }
12802     }
12803
12804     @Override
12805     public boolean isTopOfTask(IBinder token) {
12806         synchronized (this) {
12807             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12808             if (r == null) {
12809                 throw new IllegalArgumentException();
12810             }
12811             return r.task.getTopActivity() == r;
12812         }
12813     }
12814
12815     @Override
12816     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12817         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12818             String msg = "Permission Denial: setHasTopUi() from pid="
12819                     + Binder.getCallingPid()
12820                     + ", uid=" + Binder.getCallingUid()
12821                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12822             Slog.w(TAG, msg);
12823             throw new SecurityException(msg);
12824         }
12825         final int pid = Binder.getCallingPid();
12826         final long origId = Binder.clearCallingIdentity();
12827         try {
12828             synchronized (this) {
12829                 boolean changed = false;
12830                 ProcessRecord pr;
12831                 synchronized (mPidsSelfLocked) {
12832                     pr = mPidsSelfLocked.get(pid);
12833                     if (pr == null) {
12834                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12835                         return;
12836                     }
12837                     if (pr.hasTopUi != hasTopUi) {
12838                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12839                         pr.hasTopUi = hasTopUi;
12840                         changed = true;
12841                     }
12842                 }
12843                 if (changed) {
12844                     updateOomAdjLocked(pr);
12845                 }
12846             }
12847         } finally {
12848             Binder.restoreCallingIdentity(origId);
12849         }
12850     }
12851
12852     public final void enterSafeMode() {
12853         synchronized(this) {
12854             // It only makes sense to do this before the system is ready
12855             // and started launching other packages.
12856             if (!mSystemReady) {
12857                 try {
12858                     AppGlobals.getPackageManager().enterSafeMode();
12859                 } catch (RemoteException e) {
12860                 }
12861             }
12862
12863             mSafeMode = true;
12864         }
12865     }
12866
12867     public final void showSafeModeOverlay() {
12868         View v = LayoutInflater.from(mContext).inflate(
12869                 com.android.internal.R.layout.safe_mode, null);
12870         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12871         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12872         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12873         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12874         lp.gravity = Gravity.BOTTOM | Gravity.START;
12875         lp.format = v.getBackground().getOpacity();
12876         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12877                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12878         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12879         ((WindowManager)mContext.getSystemService(
12880                 Context.WINDOW_SERVICE)).addView(v, lp);
12881     }
12882
12883     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12884         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12885             return;
12886         }
12887         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12888         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12889         synchronized (stats) {
12890             if (mBatteryStatsService.isOnBattery()) {
12891                 mBatteryStatsService.enforceCallingPermission();
12892                 int MY_UID = Binder.getCallingUid();
12893                 final int uid;
12894                 if (sender == null) {
12895                     uid = sourceUid;
12896                 } else {
12897                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12898                 }
12899                 BatteryStatsImpl.Uid.Pkg pkg =
12900                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12901                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12902                 pkg.noteWakeupAlarmLocked(tag);
12903             }
12904         }
12905     }
12906
12907     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12908         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12909             return;
12910         }
12911         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12912         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12913         synchronized (stats) {
12914             mBatteryStatsService.enforceCallingPermission();
12915             int MY_UID = Binder.getCallingUid();
12916             final int uid;
12917             if (sender == null) {
12918                 uid = sourceUid;
12919             } else {
12920                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12921             }
12922             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12923         }
12924     }
12925
12926     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12927         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12928             return;
12929         }
12930         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12931         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12932         synchronized (stats) {
12933             mBatteryStatsService.enforceCallingPermission();
12934             int MY_UID = Binder.getCallingUid();
12935             final int uid;
12936             if (sender == null) {
12937                 uid = sourceUid;
12938             } else {
12939                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12940             }
12941             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12942         }
12943     }
12944
12945     public boolean killPids(int[] pids, String pReason, boolean secure) {
12946         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12947             throw new SecurityException("killPids only available to the system");
12948         }
12949         String reason = (pReason == null) ? "Unknown" : pReason;
12950         // XXX Note: don't acquire main activity lock here, because the window
12951         // manager calls in with its locks held.
12952
12953         boolean killed = false;
12954         synchronized (mPidsSelfLocked) {
12955             int worstType = 0;
12956             for (int i=0; i<pids.length; i++) {
12957                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12958                 if (proc != null) {
12959                     int type = proc.setAdj;
12960                     if (type > worstType) {
12961                         worstType = type;
12962                     }
12963                 }
12964             }
12965
12966             // If the worst oom_adj is somewhere in the cached proc LRU range,
12967             // then constrain it so we will kill all cached procs.
12968             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12969                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12970                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12971             }
12972
12973             // If this is not a secure call, don't let it kill processes that
12974             // are important.
12975             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12976                 worstType = ProcessList.SERVICE_ADJ;
12977             }
12978
12979             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12980             for (int i=0; i<pids.length; i++) {
12981                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12982                 if (proc == null) {
12983                     continue;
12984                 }
12985                 int adj = proc.setAdj;
12986                 if (adj >= worstType && !proc.killedByAm) {
12987                     proc.kill(reason, true);
12988                     killed = true;
12989                 }
12990             }
12991         }
12992         return killed;
12993     }
12994
12995     @Override
12996     public void killUid(int appId, int userId, String reason) {
12997         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12998         synchronized (this) {
12999             final long identity = Binder.clearCallingIdentity();
13000             try {
13001                 killPackageProcessesLocked(null, appId, userId,
13002                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13003                         reason != null ? reason : "kill uid");
13004             } finally {
13005                 Binder.restoreCallingIdentity(identity);
13006             }
13007         }
13008     }
13009
13010     @Override
13011     public boolean killProcessesBelowForeground(String reason) {
13012         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13013             throw new SecurityException("killProcessesBelowForeground() only available to system");
13014         }
13015
13016         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13017     }
13018
13019     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13020         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13021             throw new SecurityException("killProcessesBelowAdj() only available to system");
13022         }
13023
13024         boolean killed = false;
13025         synchronized (mPidsSelfLocked) {
13026             final int size = mPidsSelfLocked.size();
13027             for (int i = 0; i < size; i++) {
13028                 final int pid = mPidsSelfLocked.keyAt(i);
13029                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13030                 if (proc == null) continue;
13031
13032                 final int adj = proc.setAdj;
13033                 if (adj > belowAdj && !proc.killedByAm) {
13034                     proc.kill(reason, true);
13035                     killed = true;
13036                 }
13037             }
13038         }
13039         return killed;
13040     }
13041
13042     @Override
13043     public void hang(final IBinder who, boolean allowRestart) {
13044         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13045                 != PackageManager.PERMISSION_GRANTED) {
13046             throw new SecurityException("Requires permission "
13047                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13048         }
13049
13050         final IBinder.DeathRecipient death = new DeathRecipient() {
13051             @Override
13052             public void binderDied() {
13053                 synchronized (this) {
13054                     notifyAll();
13055                 }
13056             }
13057         };
13058
13059         try {
13060             who.linkToDeath(death, 0);
13061         } catch (RemoteException e) {
13062             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13063             return;
13064         }
13065
13066         synchronized (this) {
13067             Watchdog.getInstance().setAllowRestart(allowRestart);
13068             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13069             synchronized (death) {
13070                 while (who.isBinderAlive()) {
13071                     try {
13072                         death.wait();
13073                     } catch (InterruptedException e) {
13074                     }
13075                 }
13076             }
13077             Watchdog.getInstance().setAllowRestart(true);
13078         }
13079     }
13080
13081     @Override
13082     public void restart() {
13083         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13084                 != PackageManager.PERMISSION_GRANTED) {
13085             throw new SecurityException("Requires permission "
13086                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13087         }
13088
13089         Log.i(TAG, "Sending shutdown broadcast...");
13090
13091         BroadcastReceiver br = new BroadcastReceiver() {
13092             @Override public void onReceive(Context context, Intent intent) {
13093                 // Now the broadcast is done, finish up the low-level shutdown.
13094                 Log.i(TAG, "Shutting down activity manager...");
13095                 shutdown(10000);
13096                 Log.i(TAG, "Shutdown complete, restarting!");
13097                 Process.killProcess(Process.myPid());
13098                 System.exit(10);
13099             }
13100         };
13101
13102         // First send the high-level shut down broadcast.
13103         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13104         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13105         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13106         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13107         mContext.sendOrderedBroadcastAsUser(intent,
13108                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13109         */
13110         br.onReceive(mContext, intent);
13111     }
13112
13113     private long getLowRamTimeSinceIdle(long now) {
13114         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13115     }
13116
13117     @Override
13118     public void performIdleMaintenance() {
13119         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13120                 != PackageManager.PERMISSION_GRANTED) {
13121             throw new SecurityException("Requires permission "
13122                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13123         }
13124
13125         synchronized (this) {
13126             final long now = SystemClock.uptimeMillis();
13127             final long timeSinceLastIdle = now - mLastIdleTime;
13128             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13129             mLastIdleTime = now;
13130             mLowRamTimeSinceLastIdle = 0;
13131             if (mLowRamStartTime != 0) {
13132                 mLowRamStartTime = now;
13133             }
13134
13135             StringBuilder sb = new StringBuilder(128);
13136             sb.append("Idle maintenance over ");
13137             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13138             sb.append(" low RAM for ");
13139             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13140             Slog.i(TAG, sb.toString());
13141
13142             // If at least 1/3 of our time since the last idle period has been spent
13143             // with RAM low, then we want to kill processes.
13144             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13145
13146             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13147                 ProcessRecord proc = mLruProcesses.get(i);
13148                 if (proc.notCachedSinceIdle) {
13149                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13150                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13151                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13152                         if (doKilling && proc.initialIdlePss != 0
13153                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13154                             sb = new StringBuilder(128);
13155                             sb.append("Kill");
13156                             sb.append(proc.processName);
13157                             sb.append(" in idle maint: pss=");
13158                             sb.append(proc.lastPss);
13159                             sb.append(", swapPss=");
13160                             sb.append(proc.lastSwapPss);
13161                             sb.append(", initialPss=");
13162                             sb.append(proc.initialIdlePss);
13163                             sb.append(", period=");
13164                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13165                             sb.append(", lowRamPeriod=");
13166                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13167                             Slog.wtfQuiet(TAG, sb.toString());
13168                             proc.kill("idle maint (pss " + proc.lastPss
13169                                     + " from " + proc.initialIdlePss + ")", true);
13170                         }
13171                     }
13172                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13173                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13174                     proc.notCachedSinceIdle = true;
13175                     proc.initialIdlePss = 0;
13176                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13177                             mTestPssMode, isSleepingLocked(), now);
13178                 }
13179             }
13180
13181             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13182             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13183         }
13184     }
13185
13186     @Override
13187     public void sendIdleJobTrigger() {
13188         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13189                 != PackageManager.PERMISSION_GRANTED) {
13190             throw new SecurityException("Requires permission "
13191                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13192         }
13193
13194         final long ident = Binder.clearCallingIdentity();
13195         try {
13196             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13197                     .setPackage("android")
13198                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13199             broadcastIntent(null, intent, null, null, 0, null, null, null,
13200                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13201         } finally {
13202             Binder.restoreCallingIdentity(ident);
13203         }
13204     }
13205
13206     private void retrieveSettings() {
13207         final ContentResolver resolver = mContext.getContentResolver();
13208         final boolean freeformWindowManagement =
13209                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13210                         || Settings.Global.getInt(
13211                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13212         final boolean supportsPictureInPicture =
13213                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13214
13215         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13216         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13217         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13218         final boolean alwaysFinishActivities =
13219                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13220         final boolean lenientBackgroundCheck =
13221                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13222         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13223         final boolean forceResizable = Settings.Global.getInt(
13224                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13225         final boolean supportsLeanbackOnly =
13226                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13227
13228         // Transfer any global setting for forcing RTL layout, into a System Property
13229         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13230
13231         final Configuration configuration = new Configuration();
13232         Settings.System.getConfiguration(resolver, configuration);
13233         if (forceRtl) {
13234             // This will take care of setting the correct layout direction flags
13235             configuration.setLayoutDirection(configuration.locale);
13236         }
13237
13238         synchronized (this) {
13239             mDebugApp = mOrigDebugApp = debugApp;
13240             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13241             mAlwaysFinishActivities = alwaysFinishActivities;
13242             mLenientBackgroundCheck = lenientBackgroundCheck;
13243             mSupportsLeanbackOnly = supportsLeanbackOnly;
13244             mForceResizableActivities = forceResizable;
13245             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13246             if (supportsMultiWindow || forceResizable) {
13247                 mSupportsMultiWindow = true;
13248                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13249                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13250             } else {
13251                 mSupportsMultiWindow = false;
13252                 mSupportsFreeformWindowManagement = false;
13253                 mSupportsPictureInPicture = false;
13254             }
13255             // This happens before any activities are started, so we can
13256             // change mConfiguration in-place.
13257             updateConfigurationLocked(configuration, null, true);
13258             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13259                     "Initial config: " + mConfiguration);
13260
13261             // Load resources only after the current configuration has been set.
13262             final Resources res = mContext.getResources();
13263             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13264             mThumbnailWidth = res.getDimensionPixelSize(
13265                     com.android.internal.R.dimen.thumbnail_width);
13266             mThumbnailHeight = res.getDimensionPixelSize(
13267                     com.android.internal.R.dimen.thumbnail_height);
13268             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13269                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13270             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13271                     com.android.internal.R.string.config_appsNotReportingCrashes));
13272             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13273                 mFullscreenThumbnailScale = (float) res
13274                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13275                     (float) mConfiguration.screenWidthDp;
13276             } else {
13277                 mFullscreenThumbnailScale = res.getFraction(
13278                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13279             }
13280         }
13281     }
13282
13283     public boolean testIsSystemReady() {
13284         // no need to synchronize(this) just to read & return the value
13285         return mSystemReady;
13286     }
13287
13288     public void systemReady(final Runnable goingCallback) {
13289         synchronized(this) {
13290             if (mSystemReady) {
13291                 // If we're done calling all the receivers, run the next "boot phase" passed in
13292                 // by the SystemServer
13293                 if (goingCallback != null) {
13294                     goingCallback.run();
13295                 }
13296                 return;
13297             }
13298
13299             mLocalDeviceIdleController
13300                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13301
13302             // Make sure we have the current profile info, since it is needed for security checks.
13303             mUserController.onSystemReady();
13304             mRecentTasks.onSystemReadyLocked();
13305             mAppOpsService.systemReady();
13306             mSystemReady = true;
13307         }
13308
13309         ArrayList<ProcessRecord> procsToKill = null;
13310         synchronized(mPidsSelfLocked) {
13311             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13312                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13313                 if (!isAllowedWhileBooting(proc.info)){
13314                     if (procsToKill == null) {
13315                         procsToKill = new ArrayList<ProcessRecord>();
13316                     }
13317                     procsToKill.add(proc);
13318                 }
13319             }
13320         }
13321
13322         synchronized(this) {
13323             if (procsToKill != null) {
13324                 for (int i=procsToKill.size()-1; i>=0; i--) {
13325                     ProcessRecord proc = procsToKill.get(i);
13326                     Slog.i(TAG, "Removing system update proc: " + proc);
13327                     removeProcessLocked(proc, true, false, "system update done");
13328                 }
13329             }
13330
13331             // Now that we have cleaned up any update processes, we
13332             // are ready to start launching real processes and know that
13333             // we won't trample on them any more.
13334             mProcessesReady = true;
13335         }
13336
13337         Slog.i(TAG, "System now ready");
13338         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13339             SystemClock.uptimeMillis());
13340
13341         synchronized(this) {
13342             // Make sure we have no pre-ready processes sitting around.
13343
13344             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13345                 ResolveInfo ri = mContext.getPackageManager()
13346                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13347                                 STOCK_PM_FLAGS);
13348                 CharSequence errorMsg = null;
13349                 if (ri != null) {
13350                     ActivityInfo ai = ri.activityInfo;
13351                     ApplicationInfo app = ai.applicationInfo;
13352                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13353                         mTopAction = Intent.ACTION_FACTORY_TEST;
13354                         mTopData = null;
13355                         mTopComponent = new ComponentName(app.packageName,
13356                                 ai.name);
13357                     } else {
13358                         errorMsg = mContext.getResources().getText(
13359                                 com.android.internal.R.string.factorytest_not_system);
13360                     }
13361                 } else {
13362                     errorMsg = mContext.getResources().getText(
13363                             com.android.internal.R.string.factorytest_no_action);
13364                 }
13365                 if (errorMsg != null) {
13366                     mTopAction = null;
13367                     mTopData = null;
13368                     mTopComponent = null;
13369                     Message msg = Message.obtain();
13370                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13371                     msg.getData().putCharSequence("msg", errorMsg);
13372                     mUiHandler.sendMessage(msg);
13373                 }
13374             }
13375         }
13376
13377         retrieveSettings();
13378         final int currentUserId;
13379         synchronized (this) {
13380             currentUserId = mUserController.getCurrentUserIdLocked();
13381             readGrantedUriPermissionsLocked();
13382         }
13383
13384         if (goingCallback != null) goingCallback.run();
13385
13386         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13387                 Integer.toString(currentUserId), currentUserId);
13388         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13389                 Integer.toString(currentUserId), currentUserId);
13390         mSystemServiceManager.startUser(currentUserId);
13391
13392         synchronized (this) {
13393             // Only start up encryption-aware persistent apps; once user is
13394             // unlocked we'll come back around and start unaware apps
13395             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13396
13397             // Start up initial activity.
13398             mBooting = true;
13399             // Enable home activity for system user, so that the system can always boot
13400             if (UserManager.isSplitSystemUser()) {
13401                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13402                 try {
13403                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13404                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13405                             UserHandle.USER_SYSTEM);
13406                 } catch (RemoteException e) {
13407                     throw e.rethrowAsRuntimeException();
13408                 }
13409             }
13410             startHomeActivityLocked(currentUserId, "systemReady");
13411
13412             try {
13413                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13414                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13415                             + " data partition or your device will be unstable.");
13416                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13417                 }
13418             } catch (RemoteException e) {
13419             }
13420
13421             if (!Build.isBuildConsistent()) {
13422                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13423                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13424             }
13425
13426             long ident = Binder.clearCallingIdentity();
13427             try {
13428                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13429                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13430                         | Intent.FLAG_RECEIVER_FOREGROUND);
13431                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13432                 broadcastIntentLocked(null, null, intent,
13433                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13434                         null, false, false, MY_PID, Process.SYSTEM_UID,
13435                         currentUserId);
13436                 intent = new Intent(Intent.ACTION_USER_STARTING);
13437                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13438                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13439                 broadcastIntentLocked(null, null, intent,
13440                         null, new IIntentReceiver.Stub() {
13441                             @Override
13442                             public void performReceive(Intent intent, int resultCode, String data,
13443                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13444                                     throws RemoteException {
13445                             }
13446                         }, 0, null, null,
13447                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13448                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13449             } catch (Throwable t) {
13450                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13451             } finally {
13452                 Binder.restoreCallingIdentity(ident);
13453             }
13454             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13455             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13456         }
13457     }
13458
13459     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13460         synchronized (this) {
13461             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13462         }
13463     }
13464
13465     void skipCurrentReceiverLocked(ProcessRecord app) {
13466         for (BroadcastQueue queue : mBroadcastQueues) {
13467             queue.skipCurrentReceiverLocked(app);
13468         }
13469     }
13470
13471     /**
13472      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13473      * The application process will exit immediately after this call returns.
13474      * @param app object of the crashing app, null for the system server
13475      * @param crashInfo describing the exception
13476      */
13477     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13478         ProcessRecord r = findAppProcess(app, "Crash");
13479         final String processName = app == null ? "system_server"
13480                 : (r == null ? "unknown" : r.processName);
13481
13482         handleApplicationCrashInner("crash", r, processName, crashInfo);
13483     }
13484
13485     /* Native crash reporting uses this inner version because it needs to be somewhat
13486      * decoupled from the AM-managed cleanup lifecycle
13487      */
13488     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13489             ApplicationErrorReport.CrashInfo crashInfo) {
13490         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13491                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13492                 r == null ? -1 : r.info.flags,
13493                 crashInfo.exceptionClassName,
13494                 crashInfo.exceptionMessage,
13495                 crashInfo.throwFileName,
13496                 crashInfo.throwLineNumber);
13497
13498         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13499
13500         mAppErrors.crashApplication(r, crashInfo);
13501     }
13502
13503     public void handleApplicationStrictModeViolation(
13504             IBinder app,
13505             int violationMask,
13506             StrictMode.ViolationInfo info) {
13507         ProcessRecord r = findAppProcess(app, "StrictMode");
13508         if (r == null) {
13509             return;
13510         }
13511
13512         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13513             Integer stackFingerprint = info.hashCode();
13514             boolean logIt = true;
13515             synchronized (mAlreadyLoggedViolatedStacks) {
13516                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13517                     logIt = false;
13518                     // TODO: sub-sample into EventLog for these, with
13519                     // the info.durationMillis?  Then we'd get
13520                     // the relative pain numbers, without logging all
13521                     // the stack traces repeatedly.  We'd want to do
13522                     // likewise in the client code, which also does
13523                     // dup suppression, before the Binder call.
13524                 } else {
13525                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13526                         mAlreadyLoggedViolatedStacks.clear();
13527                     }
13528                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13529                 }
13530             }
13531             if (logIt) {
13532                 logStrictModeViolationToDropBox(r, info);
13533             }
13534         }
13535
13536         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13537             AppErrorResult result = new AppErrorResult();
13538             synchronized (this) {
13539                 final long origId = Binder.clearCallingIdentity();
13540
13541                 Message msg = Message.obtain();
13542                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13543                 HashMap<String, Object> data = new HashMap<String, Object>();
13544                 data.put("result", result);
13545                 data.put("app", r);
13546                 data.put("violationMask", violationMask);
13547                 data.put("info", info);
13548                 msg.obj = data;
13549                 mUiHandler.sendMessage(msg);
13550
13551                 Binder.restoreCallingIdentity(origId);
13552             }
13553             int res = result.get();
13554             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13555         }
13556     }
13557
13558     // Depending on the policy in effect, there could be a bunch of
13559     // these in quick succession so we try to batch these together to
13560     // minimize disk writes, number of dropbox entries, and maximize
13561     // compression, by having more fewer, larger records.
13562     private void logStrictModeViolationToDropBox(
13563             ProcessRecord process,
13564             StrictMode.ViolationInfo info) {
13565         if (info == null) {
13566             return;
13567         }
13568         final boolean isSystemApp = process == null ||
13569                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13570                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13571         final String processName = process == null ? "unknown" : process.processName;
13572         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13573         final DropBoxManager dbox = (DropBoxManager)
13574                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13575
13576         // Exit early if the dropbox isn't configured to accept this report type.
13577         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13578
13579         boolean bufferWasEmpty;
13580         boolean needsFlush;
13581         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13582         synchronized (sb) {
13583             bufferWasEmpty = sb.length() == 0;
13584             appendDropBoxProcessHeaders(process, processName, sb);
13585             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13586             sb.append("System-App: ").append(isSystemApp).append("\n");
13587             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13588             if (info.violationNumThisLoop != 0) {
13589                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13590             }
13591             if (info.numAnimationsRunning != 0) {
13592                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13593             }
13594             if (info.broadcastIntentAction != null) {
13595                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13596             }
13597             if (info.durationMillis != -1) {
13598                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13599             }
13600             if (info.numInstances != -1) {
13601                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13602             }
13603             if (info.tags != null) {
13604                 for (String tag : info.tags) {
13605                     sb.append("Span-Tag: ").append(tag).append("\n");
13606                 }
13607             }
13608             sb.append("\n");
13609             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13610                 sb.append(info.crashInfo.stackTrace);
13611                 sb.append("\n");
13612             }
13613             if (info.message != null) {
13614                 sb.append(info.message);
13615                 sb.append("\n");
13616             }
13617
13618             // Only buffer up to ~64k.  Various logging bits truncate
13619             // things at 128k.
13620             needsFlush = (sb.length() > 64 * 1024);
13621         }
13622
13623         // Flush immediately if the buffer's grown too large, or this
13624         // is a non-system app.  Non-system apps are isolated with a
13625         // different tag & policy and not batched.
13626         //
13627         // Batching is useful during internal testing with
13628         // StrictMode settings turned up high.  Without batching,
13629         // thousands of separate files could be created on boot.
13630         if (!isSystemApp || needsFlush) {
13631             new Thread("Error dump: " + dropboxTag) {
13632                 @Override
13633                 public void run() {
13634                     String report;
13635                     synchronized (sb) {
13636                         report = sb.toString();
13637                         sb.delete(0, sb.length());
13638                         sb.trimToSize();
13639                     }
13640                     if (report.length() != 0) {
13641                         dbox.addText(dropboxTag, report);
13642                     }
13643                 }
13644             }.start();
13645             return;
13646         }
13647
13648         // System app batching:
13649         if (!bufferWasEmpty) {
13650             // An existing dropbox-writing thread is outstanding, so
13651             // we don't need to start it up.  The existing thread will
13652             // catch the buffer appends we just did.
13653             return;
13654         }
13655
13656         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13657         // (After this point, we shouldn't access AMS internal data structures.)
13658         new Thread("Error dump: " + dropboxTag) {
13659             @Override
13660             public void run() {
13661                 // 5 second sleep to let stacks arrive and be batched together
13662                 try {
13663                     Thread.sleep(5000);  // 5 seconds
13664                 } catch (InterruptedException e) {}
13665
13666                 String errorReport;
13667                 synchronized (mStrictModeBuffer) {
13668                     errorReport = mStrictModeBuffer.toString();
13669                     if (errorReport.length() == 0) {
13670                         return;
13671                     }
13672                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13673                     mStrictModeBuffer.trimToSize();
13674                 }
13675                 dbox.addText(dropboxTag, errorReport);
13676             }
13677         }.start();
13678     }
13679
13680     /**
13681      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13682      * @param app object of the crashing app, null for the system server
13683      * @param tag reported by the caller
13684      * @param system whether this wtf is coming from the system
13685      * @param crashInfo describing the context of the error
13686      * @return true if the process should exit immediately (WTF is fatal)
13687      */
13688     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13689             final ApplicationErrorReport.CrashInfo crashInfo) {
13690         final int callingUid = Binder.getCallingUid();
13691         final int callingPid = Binder.getCallingPid();
13692
13693         if (system) {
13694             // If this is coming from the system, we could very well have low-level
13695             // system locks held, so we want to do this all asynchronously.  And we
13696             // never want this to become fatal, so there is that too.
13697             mHandler.post(new Runnable() {
13698                 @Override public void run() {
13699                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13700                 }
13701             });
13702             return false;
13703         }
13704
13705         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13706                 crashInfo);
13707
13708         if (r != null && r.pid != Process.myPid() &&
13709                 Settings.Global.getInt(mContext.getContentResolver(),
13710                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13711             mAppErrors.crashApplication(r, crashInfo);
13712             return true;
13713         } else {
13714             return false;
13715         }
13716     }
13717
13718     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13719             final ApplicationErrorReport.CrashInfo crashInfo) {
13720         final ProcessRecord r = findAppProcess(app, "WTF");
13721         final String processName = app == null ? "system_server"
13722                 : (r == null ? "unknown" : r.processName);
13723
13724         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13725                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13726
13727         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13728
13729         return r;
13730     }
13731
13732     /**
13733      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13734      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13735      */
13736     private ProcessRecord findAppProcess(IBinder app, String reason) {
13737         if (app == null) {
13738             return null;
13739         }
13740
13741         synchronized (this) {
13742             final int NP = mProcessNames.getMap().size();
13743             for (int ip=0; ip<NP; ip++) {
13744                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13745                 final int NA = apps.size();
13746                 for (int ia=0; ia<NA; ia++) {
13747                     ProcessRecord p = apps.valueAt(ia);
13748                     if (p.thread != null && p.thread.asBinder() == app) {
13749                         return p;
13750                     }
13751                 }
13752             }
13753
13754             Slog.w(TAG, "Can't find mystery application for " + reason
13755                     + " from pid=" + Binder.getCallingPid()
13756                     + " uid=" + Binder.getCallingUid() + ": " + app);
13757             return null;
13758         }
13759     }
13760
13761     /**
13762      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13763      * to append various headers to the dropbox log text.
13764      */
13765     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13766             StringBuilder sb) {
13767         // Watchdog thread ends up invoking this function (with
13768         // a null ProcessRecord) to add the stack file to dropbox.
13769         // Do not acquire a lock on this (am) in such cases, as it
13770         // could cause a potential deadlock, if and when watchdog
13771         // is invoked due to unavailability of lock on am and it
13772         // would prevent watchdog from killing system_server.
13773         if (process == null) {
13774             sb.append("Process: ").append(processName).append("\n");
13775             return;
13776         }
13777         // Note: ProcessRecord 'process' is guarded by the service
13778         // instance.  (notably process.pkgList, which could otherwise change
13779         // concurrently during execution of this method)
13780         synchronized (this) {
13781             sb.append("Process: ").append(processName).append("\n");
13782             int flags = process.info.flags;
13783             IPackageManager pm = AppGlobals.getPackageManager();
13784             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13785             for (int ip=0; ip<process.pkgList.size(); ip++) {
13786                 String pkg = process.pkgList.keyAt(ip);
13787                 sb.append("Package: ").append(pkg);
13788                 try {
13789                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13790                     if (pi != null) {
13791                         sb.append(" v").append(pi.versionCode);
13792                         if (pi.versionName != null) {
13793                             sb.append(" (").append(pi.versionName).append(")");
13794                         }
13795                     }
13796                 } catch (RemoteException e) {
13797                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13798                 }
13799                 sb.append("\n");
13800             }
13801         }
13802     }
13803
13804     private static String processClass(ProcessRecord process) {
13805         if (process == null || process.pid == MY_PID) {
13806             return "system_server";
13807         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13808             return "system_app";
13809         } else {
13810             return "data_app";
13811         }
13812     }
13813
13814     private volatile long mWtfClusterStart;
13815     private volatile int mWtfClusterCount;
13816
13817     /**
13818      * Write a description of an error (crash, WTF, ANR) to the drop box.
13819      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13820      * @param process which caused the error, null means the system server
13821      * @param activity which triggered the error, null if unknown
13822      * @param parent activity related to the error, null if unknown
13823      * @param subject line related to the error, null if absent
13824      * @param report in long form describing the error, null if absent
13825      * @param dataFile text file to include in the report, null if none
13826      * @param crashInfo giving an application stack trace, null if absent
13827      */
13828     public void addErrorToDropBox(String eventType,
13829             ProcessRecord process, String processName, ActivityRecord activity,
13830             ActivityRecord parent, String subject,
13831             final String report, final File dataFile,
13832             final ApplicationErrorReport.CrashInfo crashInfo) {
13833         // NOTE -- this must never acquire the ActivityManagerService lock,
13834         // otherwise the watchdog may be prevented from resetting the system.
13835
13836         final String dropboxTag = processClass(process) + "_" + eventType;
13837         final DropBoxManager dbox = (DropBoxManager)
13838                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13839
13840         // Exit early if the dropbox isn't configured to accept this report type.
13841         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13842
13843         // Rate-limit how often we're willing to do the heavy lifting below to
13844         // collect and record logs; currently 5 logs per 10 second period.
13845         final long now = SystemClock.elapsedRealtime();
13846         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13847             mWtfClusterStart = now;
13848             mWtfClusterCount = 1;
13849         } else {
13850             if (mWtfClusterCount++ >= 5) return;
13851         }
13852
13853         final StringBuilder sb = new StringBuilder(1024);
13854         appendDropBoxProcessHeaders(process, processName, sb);
13855         if (process != null) {
13856             sb.append("Foreground: ")
13857                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13858                     .append("\n");
13859         }
13860         if (activity != null) {
13861             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13862         }
13863         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13864             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13865         }
13866         if (parent != null && parent != activity) {
13867             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13868         }
13869         if (subject != null) {
13870             sb.append("Subject: ").append(subject).append("\n");
13871         }
13872         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13873         if (Debug.isDebuggerConnected()) {
13874             sb.append("Debugger: Connected\n");
13875         }
13876         sb.append("\n");
13877
13878         // Do the rest in a worker thread to avoid blocking the caller on I/O
13879         // (After this point, we shouldn't access AMS internal data structures.)
13880         Thread worker = new Thread("Error dump: " + dropboxTag) {
13881             @Override
13882             public void run() {
13883                 if (report != null) {
13884                     sb.append(report);
13885                 }
13886
13887                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13888                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13889                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13890                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13891
13892                 if (dataFile != null && maxDataFileSize > 0) {
13893                     try {
13894                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13895                                     "\n\n[[TRUNCATED]]"));
13896                     } catch (IOException e) {
13897                         Slog.e(TAG, "Error reading " + dataFile, e);
13898                     }
13899                 }
13900                 if (crashInfo != null && crashInfo.stackTrace != null) {
13901                     sb.append(crashInfo.stackTrace);
13902                 }
13903
13904                 if (lines > 0) {
13905                     sb.append("\n");
13906
13907                     // Merge several logcat streams, and take the last N lines
13908                     InputStreamReader input = null;
13909                     try {
13910                         java.lang.Process logcat = new ProcessBuilder(
13911                                 "/system/bin/timeout", "-k", "15s", "10s",
13912                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13913                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13914                                         .redirectErrorStream(true).start();
13915
13916                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13917                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13918                         input = new InputStreamReader(logcat.getInputStream());
13919
13920                         int num;
13921                         char[] buf = new char[8192];
13922                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13923                     } catch (IOException e) {
13924                         Slog.e(TAG, "Error running logcat", e);
13925                     } finally {
13926                         if (input != null) try { input.close(); } catch (IOException e) {}
13927                     }
13928                 }
13929
13930                 dbox.addText(dropboxTag, sb.toString());
13931             }
13932         };
13933
13934         if (process == null) {
13935             // If process is null, we are being called from some internal code
13936             // and may be about to die -- run this synchronously.
13937             worker.run();
13938         } else {
13939             worker.start();
13940         }
13941     }
13942
13943     @Override
13944     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13945         enforceNotIsolatedCaller("getProcessesInErrorState");
13946         // assume our apps are happy - lazy create the list
13947         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13948
13949         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13950                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13951         int userId = UserHandle.getUserId(Binder.getCallingUid());
13952
13953         synchronized (this) {
13954
13955             // iterate across all processes
13956             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13957                 ProcessRecord app = mLruProcesses.get(i);
13958                 if (!allUsers && app.userId != userId) {
13959                     continue;
13960                 }
13961                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13962                     // This one's in trouble, so we'll generate a report for it
13963                     // crashes are higher priority (in case there's a crash *and* an anr)
13964                     ActivityManager.ProcessErrorStateInfo report = null;
13965                     if (app.crashing) {
13966                         report = app.crashingReport;
13967                     } else if (app.notResponding) {
13968                         report = app.notRespondingReport;
13969                     }
13970
13971                     if (report != null) {
13972                         if (errList == null) {
13973                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13974                         }
13975                         errList.add(report);
13976                     } else {
13977                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13978                                 " crashing = " + app.crashing +
13979                                 " notResponding = " + app.notResponding);
13980                     }
13981                 }
13982             }
13983         }
13984
13985         return errList;
13986     }
13987
13988     static int procStateToImportance(int procState, int memAdj,
13989             ActivityManager.RunningAppProcessInfo currApp) {
13990         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13991         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13992             currApp.lru = memAdj;
13993         } else {
13994             currApp.lru = 0;
13995         }
13996         return imp;
13997     }
13998
13999     private void fillInProcMemInfo(ProcessRecord app,
14000             ActivityManager.RunningAppProcessInfo outInfo) {
14001         outInfo.pid = app.pid;
14002         outInfo.uid = app.info.uid;
14003         if (mHeavyWeightProcess == app) {
14004             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14005         }
14006         if (app.persistent) {
14007             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14008         }
14009         if (app.activities.size() > 0) {
14010             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14011         }
14012         outInfo.lastTrimLevel = app.trimMemoryLevel;
14013         int adj = app.curAdj;
14014         int procState = app.curProcState;
14015         outInfo.importance = procStateToImportance(procState, adj, outInfo);
14016         outInfo.importanceReasonCode = app.adjTypeCode;
14017         outInfo.processState = app.curProcState;
14018     }
14019
14020     @Override
14021     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14022         enforceNotIsolatedCaller("getRunningAppProcesses");
14023
14024         final int callingUid = Binder.getCallingUid();
14025
14026         // Lazy instantiation of list
14027         List<ActivityManager.RunningAppProcessInfo> runList = null;
14028         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14029                 callingUid) == PackageManager.PERMISSION_GRANTED;
14030         final int userId = UserHandle.getUserId(callingUid);
14031         final boolean allUids = isGetTasksAllowed(
14032                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14033
14034         synchronized (this) {
14035             // Iterate across all processes
14036             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14037                 ProcessRecord app = mLruProcesses.get(i);
14038                 if ((!allUsers && app.userId != userId)
14039                         || (!allUids && app.uid != callingUid)) {
14040                     continue;
14041                 }
14042                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14043                     // Generate process state info for running application
14044                     ActivityManager.RunningAppProcessInfo currApp =
14045                         new ActivityManager.RunningAppProcessInfo(app.processName,
14046                                 app.pid, app.getPackageList());
14047                     fillInProcMemInfo(app, currApp);
14048                     if (app.adjSource instanceof ProcessRecord) {
14049                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14050                         currApp.importanceReasonImportance =
14051                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14052                                         app.adjSourceProcState);
14053                     } else if (app.adjSource instanceof ActivityRecord) {
14054                         ActivityRecord r = (ActivityRecord)app.adjSource;
14055                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14056                     }
14057                     if (app.adjTarget instanceof ComponentName) {
14058                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14059                     }
14060                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14061                     //        + " lru=" + currApp.lru);
14062                     if (runList == null) {
14063                         runList = new ArrayList<>();
14064                     }
14065                     runList.add(currApp);
14066                 }
14067             }
14068         }
14069         return runList;
14070     }
14071
14072     @Override
14073     public List<ApplicationInfo> getRunningExternalApplications() {
14074         enforceNotIsolatedCaller("getRunningExternalApplications");
14075         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14076         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14077         if (runningApps != null && runningApps.size() > 0) {
14078             Set<String> extList = new HashSet<String>();
14079             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14080                 if (app.pkgList != null) {
14081                     for (String pkg : app.pkgList) {
14082                         extList.add(pkg);
14083                     }
14084                 }
14085             }
14086             IPackageManager pm = AppGlobals.getPackageManager();
14087             for (String pkg : extList) {
14088                 try {
14089                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14090                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14091                         retList.add(info);
14092                     }
14093                 } catch (RemoteException e) {
14094                 }
14095             }
14096         }
14097         return retList;
14098     }
14099
14100     @Override
14101     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14102         enforceNotIsolatedCaller("getMyMemoryState");
14103         synchronized (this) {
14104             ProcessRecord proc;
14105             synchronized (mPidsSelfLocked) {
14106                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14107             }
14108             fillInProcMemInfo(proc, outInfo);
14109         }
14110     }
14111
14112     @Override
14113     public int getMemoryTrimLevel() {
14114         enforceNotIsolatedCaller("getMyMemoryState");
14115         synchronized (this) {
14116             return mLastMemoryLevel;
14117         }
14118     }
14119
14120     @Override
14121     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14122             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14123         (new ActivityManagerShellCommand(this, false)).exec(
14124                 this, in, out, err, args, resultReceiver);
14125     }
14126
14127     @Override
14128     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14129         if (checkCallingPermission(android.Manifest.permission.DUMP)
14130                 != PackageManager.PERMISSION_GRANTED) {
14131             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14132                     + Binder.getCallingPid()
14133                     + ", uid=" + Binder.getCallingUid()
14134                     + " without permission "
14135                     + android.Manifest.permission.DUMP);
14136             return;
14137         }
14138
14139         boolean dumpAll = false;
14140         boolean dumpClient = false;
14141         boolean dumpCheckin = false;
14142         boolean dumpCheckinFormat = false;
14143         String dumpPackage = null;
14144
14145         int opti = 0;
14146         while (opti < args.length) {
14147             String opt = args[opti];
14148             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14149                 break;
14150             }
14151             opti++;
14152             if ("-a".equals(opt)) {
14153                 dumpAll = true;
14154             } else if ("-c".equals(opt)) {
14155                 dumpClient = true;
14156             } else if ("-p".equals(opt)) {
14157                 if (opti < args.length) {
14158                     dumpPackage = args[opti];
14159                     opti++;
14160                 } else {
14161                     pw.println("Error: -p option requires package argument");
14162                     return;
14163                 }
14164                 dumpClient = true;
14165             } else if ("--checkin".equals(opt)) {
14166                 dumpCheckin = dumpCheckinFormat = true;
14167             } else if ("-C".equals(opt)) {
14168                 dumpCheckinFormat = true;
14169             } else if ("-h".equals(opt)) {
14170                 ActivityManagerShellCommand.dumpHelp(pw, true);
14171                 return;
14172             } else {
14173                 pw.println("Unknown argument: " + opt + "; use -h for help");
14174             }
14175         }
14176
14177         long origId = Binder.clearCallingIdentity();
14178         boolean more = false;
14179         // Is the caller requesting to dump a particular piece of data?
14180         if (opti < args.length) {
14181             String cmd = args[opti];
14182             opti++;
14183             if ("activities".equals(cmd) || "a".equals(cmd)) {
14184                 synchronized (this) {
14185                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14186                 }
14187             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14188                 synchronized (this) {
14189                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14190                 }
14191             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14192                 String[] newArgs;
14193                 String name;
14194                 if (opti >= args.length) {
14195                     name = null;
14196                     newArgs = EMPTY_STRING_ARRAY;
14197                 } else {
14198                     dumpPackage = args[opti];
14199                     opti++;
14200                     newArgs = new String[args.length - opti];
14201                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14202                             args.length - opti);
14203                 }
14204                 synchronized (this) {
14205                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14206                 }
14207             } else if ("broadcast-stats".equals(cmd)) {
14208                 String[] newArgs;
14209                 String name;
14210                 if (opti >= args.length) {
14211                     name = null;
14212                     newArgs = EMPTY_STRING_ARRAY;
14213                 } else {
14214                     dumpPackage = args[opti];
14215                     opti++;
14216                     newArgs = new String[args.length - opti];
14217                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14218                             args.length - opti);
14219                 }
14220                 synchronized (this) {
14221                     if (dumpCheckinFormat) {
14222                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14223                                 dumpPackage);
14224                     } else {
14225                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14226                     }
14227                 }
14228             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14229                 String[] newArgs;
14230                 String name;
14231                 if (opti >= args.length) {
14232                     name = null;
14233                     newArgs = EMPTY_STRING_ARRAY;
14234                 } else {
14235                     dumpPackage = args[opti];
14236                     opti++;
14237                     newArgs = new String[args.length - opti];
14238                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14239                             args.length - opti);
14240                 }
14241                 synchronized (this) {
14242                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14243                 }
14244             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14245                 String[] newArgs;
14246                 String name;
14247                 if (opti >= args.length) {
14248                     name = null;
14249                     newArgs = EMPTY_STRING_ARRAY;
14250                 } else {
14251                     dumpPackage = args[opti];
14252                     opti++;
14253                     newArgs = new String[args.length - opti];
14254                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14255                             args.length - opti);
14256                 }
14257                 synchronized (this) {
14258                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14259                 }
14260             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14261                 synchronized (this) {
14262                     dumpOomLocked(fd, pw, args, opti, true);
14263                 }
14264             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14265                 synchronized (this) {
14266                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14267                 }
14268             } else if ("provider".equals(cmd)) {
14269                 String[] newArgs;
14270                 String name;
14271                 if (opti >= args.length) {
14272                     name = null;
14273                     newArgs = EMPTY_STRING_ARRAY;
14274                 } else {
14275                     name = args[opti];
14276                     opti++;
14277                     newArgs = new String[args.length - opti];
14278                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14279                 }
14280                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14281                     pw.println("No providers match: " + name);
14282                     pw.println("Use -h for help.");
14283                 }
14284             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14285                 synchronized (this) {
14286                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14287                 }
14288             } else if ("service".equals(cmd)) {
14289                 String[] newArgs;
14290                 String name;
14291                 if (opti >= args.length) {
14292                     name = null;
14293                     newArgs = EMPTY_STRING_ARRAY;
14294                 } else {
14295                     name = args[opti];
14296                     opti++;
14297                     newArgs = new String[args.length - opti];
14298                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14299                             args.length - opti);
14300                 }
14301                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14302                     pw.println("No services match: " + name);
14303                     pw.println("Use -h for help.");
14304                 }
14305             } else if ("package".equals(cmd)) {
14306                 String[] newArgs;
14307                 if (opti >= args.length) {
14308                     pw.println("package: no package name specified");
14309                     pw.println("Use -h for help.");
14310                 } else {
14311                     dumpPackage = args[opti];
14312                     opti++;
14313                     newArgs = new String[args.length - opti];
14314                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14315                             args.length - opti);
14316                     args = newArgs;
14317                     opti = 0;
14318                     more = true;
14319                 }
14320             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14321                 synchronized (this) {
14322                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14323                 }
14324             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14325                 if (dumpClient) {
14326                     ActiveServices.ServiceDumper dumper;
14327                     synchronized (this) {
14328                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14329                                 dumpPackage);
14330                     }
14331                     dumper.dumpWithClient();
14332                 } else {
14333                     synchronized (this) {
14334                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14335                                 dumpPackage).dumpLocked();
14336                     }
14337                 }
14338             } else if ("locks".equals(cmd)) {
14339                 LockGuard.dump(fd, pw, args);
14340             } else {
14341                 // Dumping a single activity?
14342                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14343                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14344                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14345                     if (res < 0) {
14346                         pw.println("Bad activity command, or no activities match: " + cmd);
14347                         pw.println("Use -h for help.");
14348                     }
14349                 }
14350             }
14351             if (!more) {
14352                 Binder.restoreCallingIdentity(origId);
14353                 return;
14354             }
14355         }
14356
14357         // No piece of data specified, dump everything.
14358         if (dumpCheckinFormat) {
14359             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14360         } else if (dumpClient) {
14361             ActiveServices.ServiceDumper sdumper;
14362             synchronized (this) {
14363                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14364                 pw.println();
14365                 if (dumpAll) {
14366                     pw.println("-------------------------------------------------------------------------------");
14367                 }
14368                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14369                 pw.println();
14370                 if (dumpAll) {
14371                     pw.println("-------------------------------------------------------------------------------");
14372                 }
14373                 if (dumpAll || dumpPackage != null) {
14374                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14375                     pw.println();
14376                     if (dumpAll) {
14377                         pw.println("-------------------------------------------------------------------------------");
14378                     }
14379                 }
14380                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14381                 pw.println();
14382                 if (dumpAll) {
14383                     pw.println("-------------------------------------------------------------------------------");
14384                 }
14385                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14386                 pw.println();
14387                 if (dumpAll) {
14388                     pw.println("-------------------------------------------------------------------------------");
14389                 }
14390                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14391                         dumpPackage);
14392             }
14393             sdumper.dumpWithClient();
14394             pw.println();
14395             synchronized (this) {
14396                 if (dumpAll) {
14397                     pw.println("-------------------------------------------------------------------------------");
14398                 }
14399                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14400                 pw.println();
14401                 if (dumpAll) {
14402                     pw.println("-------------------------------------------------------------------------------");
14403                 }
14404                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14405                 if (mAssociations.size() > 0) {
14406                     pw.println();
14407                     if (dumpAll) {
14408                         pw.println("-------------------------------------------------------------------------------");
14409                     }
14410                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14411                 }
14412                 pw.println();
14413                 if (dumpAll) {
14414                     pw.println("-------------------------------------------------------------------------------");
14415                 }
14416                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14417             }
14418
14419         } else {
14420             synchronized (this) {
14421                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14422                 pw.println();
14423                 if (dumpAll) {
14424                     pw.println("-------------------------------------------------------------------------------");
14425                 }
14426                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14427                 pw.println();
14428                 if (dumpAll) {
14429                     pw.println("-------------------------------------------------------------------------------");
14430                 }
14431                 if (dumpAll || dumpPackage != null) {
14432                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14433                     pw.println();
14434                     if (dumpAll) {
14435                         pw.println("-------------------------------------------------------------------------------");
14436                     }
14437                 }
14438                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14439                 pw.println();
14440                 if (dumpAll) {
14441                     pw.println("-------------------------------------------------------------------------------");
14442                 }
14443                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14444                 pw.println();
14445                 if (dumpAll) {
14446                     pw.println("-------------------------------------------------------------------------------");
14447                 }
14448                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14449                         .dumpLocked();
14450                 pw.println();
14451                 if (dumpAll) {
14452                     pw.println("-------------------------------------------------------------------------------");
14453                 }
14454                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14455                 pw.println();
14456                 if (dumpAll) {
14457                     pw.println("-------------------------------------------------------------------------------");
14458                 }
14459                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14460                 if (mAssociations.size() > 0) {
14461                     pw.println();
14462                     if (dumpAll) {
14463                         pw.println("-------------------------------------------------------------------------------");
14464                     }
14465                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14466                 }
14467                 pw.println();
14468                 if (dumpAll) {
14469                     pw.println("-------------------------------------------------------------------------------");
14470                 }
14471                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14472             }
14473         }
14474         Binder.restoreCallingIdentity(origId);
14475     }
14476
14477     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14478             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14479         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14480
14481         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14482                 dumpPackage);
14483         boolean needSep = printedAnything;
14484
14485         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14486                 dumpPackage, needSep, "  mFocusedActivity: ");
14487         if (printed) {
14488             printedAnything = true;
14489             needSep = false;
14490         }
14491
14492         if (dumpPackage == null) {
14493             if (needSep) {
14494                 pw.println();
14495             }
14496             needSep = true;
14497             printedAnything = true;
14498             mStackSupervisor.dump(pw, "  ");
14499         }
14500
14501         if (!printedAnything) {
14502             pw.println("  (nothing)");
14503         }
14504     }
14505
14506     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14507             int opti, boolean dumpAll, String dumpPackage) {
14508         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14509
14510         boolean printedAnything = false;
14511
14512         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14513             boolean printedHeader = false;
14514
14515             final int N = mRecentTasks.size();
14516             for (int i=0; i<N; i++) {
14517                 TaskRecord tr = mRecentTasks.get(i);
14518                 if (dumpPackage != null) {
14519                     if (tr.realActivity == null ||
14520                             !dumpPackage.equals(tr.realActivity)) {
14521                         continue;
14522                     }
14523                 }
14524                 if (!printedHeader) {
14525                     pw.println("  Recent tasks:");
14526                     printedHeader = true;
14527                     printedAnything = true;
14528                 }
14529                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14530                         pw.println(tr);
14531                 if (dumpAll) {
14532                     mRecentTasks.get(i).dump(pw, "    ");
14533                 }
14534             }
14535         }
14536
14537         if (!printedAnything) {
14538             pw.println("  (nothing)");
14539         }
14540     }
14541
14542     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14543             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14544         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14545
14546         int dumpUid = 0;
14547         if (dumpPackage != null) {
14548             IPackageManager pm = AppGlobals.getPackageManager();
14549             try {
14550                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14551             } catch (RemoteException e) {
14552             }
14553         }
14554
14555         boolean printedAnything = false;
14556
14557         final long now = SystemClock.uptimeMillis();
14558
14559         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14560             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14561                     = mAssociations.valueAt(i1);
14562             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14563                 SparseArray<ArrayMap<String, Association>> sourceUids
14564                         = targetComponents.valueAt(i2);
14565                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14566                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14567                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14568                         Association ass = sourceProcesses.valueAt(i4);
14569                         if (dumpPackage != null) {
14570                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14571                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14572                                 continue;
14573                             }
14574                         }
14575                         printedAnything = true;
14576                         pw.print("  ");
14577                         pw.print(ass.mTargetProcess);
14578                         pw.print("/");
14579                         UserHandle.formatUid(pw, ass.mTargetUid);
14580                         pw.print(" <- ");
14581                         pw.print(ass.mSourceProcess);
14582                         pw.print("/");
14583                         UserHandle.formatUid(pw, ass.mSourceUid);
14584                         pw.println();
14585                         pw.print("    via ");
14586                         pw.print(ass.mTargetComponent.flattenToShortString());
14587                         pw.println();
14588                         pw.print("    ");
14589                         long dur = ass.mTime;
14590                         if (ass.mNesting > 0) {
14591                             dur += now - ass.mStartTime;
14592                         }
14593                         TimeUtils.formatDuration(dur, pw);
14594                         pw.print(" (");
14595                         pw.print(ass.mCount);
14596                         pw.print(" times)");
14597                         pw.print("  ");
14598                         for (int i=0; i<ass.mStateTimes.length; i++) {
14599                             long amt = ass.mStateTimes[i];
14600                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14601                                 amt += now - ass.mLastStateUptime;
14602                             }
14603                             if (amt != 0) {
14604                                 pw.print(" ");
14605                                 pw.print(ProcessList.makeProcStateString(
14606                                             i + ActivityManager.MIN_PROCESS_STATE));
14607                                 pw.print("=");
14608                                 TimeUtils.formatDuration(amt, pw);
14609                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14610                                     pw.print("*");
14611                                 }
14612                             }
14613                         }
14614                         pw.println();
14615                         if (ass.mNesting > 0) {
14616                             pw.print("    Currently active: ");
14617                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14618                             pw.println();
14619                         }
14620                     }
14621                 }
14622             }
14623
14624         }
14625
14626         if (!printedAnything) {
14627             pw.println("  (nothing)");
14628         }
14629     }
14630
14631     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14632             String header, boolean needSep) {
14633         boolean printed = false;
14634         int whichAppId = -1;
14635         if (dumpPackage != null) {
14636             try {
14637                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14638                         dumpPackage, 0);
14639                 whichAppId = UserHandle.getAppId(info.uid);
14640             } catch (NameNotFoundException e) {
14641                 e.printStackTrace();
14642             }
14643         }
14644         for (int i=0; i<uids.size(); i++) {
14645             UidRecord uidRec = uids.valueAt(i);
14646             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14647                 continue;
14648             }
14649             if (!printed) {
14650                 printed = true;
14651                 if (needSep) {
14652                     pw.println();
14653                 }
14654                 pw.print("  ");
14655                 pw.println(header);
14656                 needSep = true;
14657             }
14658             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14659             pw.print(": "); pw.println(uidRec);
14660         }
14661         return printed;
14662     }
14663
14664     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14665             int opti, boolean dumpAll, String dumpPackage) {
14666         boolean needSep = false;
14667         boolean printedAnything = false;
14668         int numPers = 0;
14669
14670         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14671
14672         if (dumpAll) {
14673             final int NP = mProcessNames.getMap().size();
14674             for (int ip=0; ip<NP; ip++) {
14675                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14676                 final int NA = procs.size();
14677                 for (int ia=0; ia<NA; ia++) {
14678                     ProcessRecord r = procs.valueAt(ia);
14679                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14680                         continue;
14681                     }
14682                     if (!needSep) {
14683                         pw.println("  All known processes:");
14684                         needSep = true;
14685                         printedAnything = true;
14686                     }
14687                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14688                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14689                         pw.print(" "); pw.println(r);
14690                     r.dump(pw, "    ");
14691                     if (r.persistent) {
14692                         numPers++;
14693                     }
14694                 }
14695             }
14696         }
14697
14698         if (mIsolatedProcesses.size() > 0) {
14699             boolean printed = false;
14700             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14701                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14702                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14703                     continue;
14704                 }
14705                 if (!printed) {
14706                     if (needSep) {
14707                         pw.println();
14708                     }
14709                     pw.println("  Isolated process list (sorted by uid):");
14710                     printedAnything = true;
14711                     printed = true;
14712                     needSep = true;
14713                 }
14714                 pw.println(String.format("%sIsolated #%2d: %s",
14715                         "    ", i, r.toString()));
14716             }
14717         }
14718
14719         if (mActiveUids.size() > 0) {
14720             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14721                 printedAnything = needSep = true;
14722             }
14723         }
14724         if (mValidateUids.size() > 0) {
14725             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14726                 printedAnything = needSep = true;
14727             }
14728         }
14729
14730         if (mLruProcesses.size() > 0) {
14731             if (needSep) {
14732                 pw.println();
14733             }
14734             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14735                     pw.print(" total, non-act at ");
14736                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14737                     pw.print(", non-svc at ");
14738                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14739                     pw.println("):");
14740             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14741             needSep = true;
14742             printedAnything = true;
14743         }
14744
14745         if (dumpAll || dumpPackage != null) {
14746             synchronized (mPidsSelfLocked) {
14747                 boolean printed = false;
14748                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14749                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14750                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14751                         continue;
14752                     }
14753                     if (!printed) {
14754                         if (needSep) pw.println();
14755                         needSep = true;
14756                         pw.println("  PID mappings:");
14757                         printed = true;
14758                         printedAnything = true;
14759                     }
14760                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14761                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14762                 }
14763             }
14764         }
14765
14766         if (mForegroundProcesses.size() > 0) {
14767             synchronized (mPidsSelfLocked) {
14768                 boolean printed = false;
14769                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14770                     ProcessRecord r = mPidsSelfLocked.get(
14771                             mForegroundProcesses.valueAt(i).pid);
14772                     if (dumpPackage != null && (r == null
14773                             || !r.pkgList.containsKey(dumpPackage))) {
14774                         continue;
14775                     }
14776                     if (!printed) {
14777                         if (needSep) pw.println();
14778                         needSep = true;
14779                         pw.println("  Foreground Processes:");
14780                         printed = true;
14781                         printedAnything = true;
14782                     }
14783                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14784                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14785                 }
14786             }
14787         }
14788
14789         if (mPersistentStartingProcesses.size() > 0) {
14790             if (needSep) pw.println();
14791             needSep = true;
14792             printedAnything = true;
14793             pw.println("  Persisent processes that are starting:");
14794             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14795                     "Starting Norm", "Restarting PERS", dumpPackage);
14796         }
14797
14798         if (mRemovedProcesses.size() > 0) {
14799             if (needSep) pw.println();
14800             needSep = true;
14801             printedAnything = true;
14802             pw.println("  Processes that are being removed:");
14803             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14804                     "Removed Norm", "Removed PERS", dumpPackage);
14805         }
14806
14807         if (mProcessesOnHold.size() > 0) {
14808             if (needSep) pw.println();
14809             needSep = true;
14810             printedAnything = true;
14811             pw.println("  Processes that are on old until the system is ready:");
14812             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14813                     "OnHold Norm", "OnHold PERS", dumpPackage);
14814         }
14815
14816         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14817
14818         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14819         if (needSep) {
14820             printedAnything = true;
14821         }
14822
14823         if (dumpPackage == null) {
14824             pw.println();
14825             needSep = false;
14826             mUserController.dump(pw, dumpAll);
14827         }
14828         if (mHomeProcess != null && (dumpPackage == null
14829                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14830             if (needSep) {
14831                 pw.println();
14832                 needSep = false;
14833             }
14834             pw.println("  mHomeProcess: " + mHomeProcess);
14835         }
14836         if (mPreviousProcess != null && (dumpPackage == null
14837                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14838             if (needSep) {
14839                 pw.println();
14840                 needSep = false;
14841             }
14842             pw.println("  mPreviousProcess: " + mPreviousProcess);
14843         }
14844         if (dumpAll) {
14845             StringBuilder sb = new StringBuilder(128);
14846             sb.append("  mPreviousProcessVisibleTime: ");
14847             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14848             pw.println(sb);
14849         }
14850         if (mHeavyWeightProcess != null && (dumpPackage == null
14851                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14852             if (needSep) {
14853                 pw.println();
14854                 needSep = false;
14855             }
14856             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14857         }
14858         if (dumpPackage == null) {
14859             pw.println("  mConfiguration: " + mConfiguration);
14860         }
14861         if (dumpAll) {
14862             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14863             if (mCompatModePackages.getPackages().size() > 0) {
14864                 boolean printed = false;
14865                 for (Map.Entry<String, Integer> entry
14866                         : mCompatModePackages.getPackages().entrySet()) {
14867                     String pkg = entry.getKey();
14868                     int mode = entry.getValue();
14869                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14870                         continue;
14871                     }
14872                     if (!printed) {
14873                         pw.println("  mScreenCompatPackages:");
14874                         printed = true;
14875                     }
14876                     pw.print("    "); pw.print(pkg); pw.print(": ");
14877                             pw.print(mode); pw.println();
14878                 }
14879             }
14880         }
14881         if (dumpPackage == null) {
14882             pw.println("  mWakefulness="
14883                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14884             pw.println("  mSleepTokens=" + mSleepTokens);
14885             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14886                     + lockScreenShownToString());
14887             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14888             if (mRunningVoice != null) {
14889                 pw.println("  mRunningVoice=" + mRunningVoice);
14890                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14891             }
14892         }
14893         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14894                 || mOrigWaitForDebugger) {
14895             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14896                     || dumpPackage.equals(mOrigDebugApp)) {
14897                 if (needSep) {
14898                     pw.println();
14899                     needSep = false;
14900                 }
14901                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14902                         + " mDebugTransient=" + mDebugTransient
14903                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14904             }
14905         }
14906         if (mCurAppTimeTracker != null) {
14907             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14908         }
14909         if (mMemWatchProcesses.getMap().size() > 0) {
14910             pw.println("  Mem watch processes:");
14911             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14912                     = mMemWatchProcesses.getMap();
14913             for (int i=0; i<procs.size(); i++) {
14914                 final String proc = procs.keyAt(i);
14915                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14916                 for (int j=0; j<uids.size(); j++) {
14917                     if (needSep) {
14918                         pw.println();
14919                         needSep = false;
14920                     }
14921                     StringBuilder sb = new StringBuilder();
14922                     sb.append("    ").append(proc).append('/');
14923                     UserHandle.formatUid(sb, uids.keyAt(j));
14924                     Pair<Long, String> val = uids.valueAt(j);
14925                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14926                     if (val.second != null) {
14927                         sb.append(", report to ").append(val.second);
14928                     }
14929                     pw.println(sb.toString());
14930                 }
14931             }
14932             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14933             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14934             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14935                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14936         }
14937         if (mTrackAllocationApp != null) {
14938             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14939                 if (needSep) {
14940                     pw.println();
14941                     needSep = false;
14942                 }
14943                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14944             }
14945         }
14946         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14947                 || mProfileFd != null) {
14948             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14949                 if (needSep) {
14950                     pw.println();
14951                     needSep = false;
14952                 }
14953                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14954                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14955                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14956                         + mAutoStopProfiler);
14957                 pw.println("  mProfileType=" + mProfileType);
14958             }
14959         }
14960         if (mNativeDebuggingApp != null) {
14961             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14962                 if (needSep) {
14963                     pw.println();
14964                     needSep = false;
14965                 }
14966                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14967             }
14968         }
14969         if (dumpPackage == null) {
14970             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14971                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14972                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14973             }
14974             if (mController != null) {
14975                 pw.println("  mController=" + mController
14976                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14977             }
14978             if (dumpAll) {
14979                 pw.println("  Total persistent processes: " + numPers);
14980                 pw.println("  mProcessesReady=" + mProcessesReady
14981                         + " mSystemReady=" + mSystemReady
14982                         + " mBooted=" + mBooted
14983                         + " mFactoryTest=" + mFactoryTest);
14984                 pw.println("  mBooting=" + mBooting
14985                         + " mCallFinishBooting=" + mCallFinishBooting
14986                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14987                 pw.print("  mLastPowerCheckRealtime=");
14988                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14989                         pw.println("");
14990                 pw.print("  mLastPowerCheckUptime=");
14991                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14992                         pw.println("");
14993                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14994                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14995                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14996                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14997                         + " (" + mLruProcesses.size() + " total)"
14998                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14999                         + " mNumServiceProcs=" + mNumServiceProcs
15000                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15001                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15002                         + " mLastMemoryLevel=" + mLastMemoryLevel
15003                         + " mLastNumProcesses=" + mLastNumProcesses);
15004                 long now = SystemClock.uptimeMillis();
15005                 pw.print("  mLastIdleTime=");
15006                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15007                         pw.print(" mLowRamSinceLastIdle=");
15008                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15009                         pw.println();
15010             }
15011         }
15012
15013         if (!printedAnything) {
15014             pw.println("  (nothing)");
15015         }
15016     }
15017
15018     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15019             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15020         if (mProcessesToGc.size() > 0) {
15021             boolean printed = false;
15022             long now = SystemClock.uptimeMillis();
15023             for (int i=0; i<mProcessesToGc.size(); i++) {
15024                 ProcessRecord proc = mProcessesToGc.get(i);
15025                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15026                     continue;
15027                 }
15028                 if (!printed) {
15029                     if (needSep) pw.println();
15030                     needSep = true;
15031                     pw.println("  Processes that are waiting to GC:");
15032                     printed = true;
15033                 }
15034                 pw.print("    Process "); pw.println(proc);
15035                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15036                         pw.print(", last gced=");
15037                         pw.print(now-proc.lastRequestedGc);
15038                         pw.print(" ms ago, last lowMem=");
15039                         pw.print(now-proc.lastLowMemory);
15040                         pw.println(" ms ago");
15041
15042             }
15043         }
15044         return needSep;
15045     }
15046
15047     void printOomLevel(PrintWriter pw, String name, int adj) {
15048         pw.print("    ");
15049         if (adj >= 0) {
15050             pw.print(' ');
15051             if (adj < 10) pw.print(' ');
15052         } else {
15053             if (adj > -10) pw.print(' ');
15054         }
15055         pw.print(adj);
15056         pw.print(": ");
15057         pw.print(name);
15058         pw.print(" (");
15059         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15060         pw.println(")");
15061     }
15062
15063     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15064             int opti, boolean dumpAll) {
15065         boolean needSep = false;
15066
15067         if (mLruProcesses.size() > 0) {
15068             if (needSep) pw.println();
15069             needSep = true;
15070             pw.println("  OOM levels:");
15071             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15072             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15073             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15074             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15075             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15076             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15077             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15078             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15079             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15080             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15081             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15082             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15083             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15084             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15085
15086             if (needSep) pw.println();
15087             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15088                     pw.print(" total, non-act at ");
15089                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15090                     pw.print(", non-svc at ");
15091                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15092                     pw.println("):");
15093             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15094             needSep = true;
15095         }
15096
15097         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15098
15099         pw.println();
15100         pw.println("  mHomeProcess: " + mHomeProcess);
15101         pw.println("  mPreviousProcess: " + mPreviousProcess);
15102         if (mHeavyWeightProcess != null) {
15103             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15104         }
15105
15106         return true;
15107     }
15108
15109     /**
15110      * There are three ways to call this:
15111      *  - no provider specified: dump all the providers
15112      *  - a flattened component name that matched an existing provider was specified as the
15113      *    first arg: dump that one provider
15114      *  - the first arg isn't the flattened component name of an existing provider:
15115      *    dump all providers whose component contains the first arg as a substring
15116      */
15117     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15118             int opti, boolean dumpAll) {
15119         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15120     }
15121
15122     static class ItemMatcher {
15123         ArrayList<ComponentName> components;
15124         ArrayList<String> strings;
15125         ArrayList<Integer> objects;
15126         boolean all;
15127
15128         ItemMatcher() {
15129             all = true;
15130         }
15131
15132         void build(String name) {
15133             ComponentName componentName = ComponentName.unflattenFromString(name);
15134             if (componentName != null) {
15135                 if (components == null) {
15136                     components = new ArrayList<ComponentName>();
15137                 }
15138                 components.add(componentName);
15139                 all = false;
15140             } else {
15141                 int objectId = 0;
15142                 // Not a '/' separated full component name; maybe an object ID?
15143                 try {
15144                     objectId = Integer.parseInt(name, 16);
15145                     if (objects == null) {
15146                         objects = new ArrayList<Integer>();
15147                     }
15148                     objects.add(objectId);
15149                     all = false;
15150                 } catch (RuntimeException e) {
15151                     // Not an integer; just do string match.
15152                     if (strings == null) {
15153                         strings = new ArrayList<String>();
15154                     }
15155                     strings.add(name);
15156                     all = false;
15157                 }
15158             }
15159         }
15160
15161         int build(String[] args, int opti) {
15162             for (; opti<args.length; opti++) {
15163                 String name = args[opti];
15164                 if ("--".equals(name)) {
15165                     return opti+1;
15166                 }
15167                 build(name);
15168             }
15169             return opti;
15170         }
15171
15172         boolean match(Object object, ComponentName comp) {
15173             if (all) {
15174                 return true;
15175             }
15176             if (components != null) {
15177                 for (int i=0; i<components.size(); i++) {
15178                     if (components.get(i).equals(comp)) {
15179                         return true;
15180                     }
15181                 }
15182             }
15183             if (objects != null) {
15184                 for (int i=0; i<objects.size(); i++) {
15185                     if (System.identityHashCode(object) == objects.get(i)) {
15186                         return true;
15187                     }
15188                 }
15189             }
15190             if (strings != null) {
15191                 String flat = comp.flattenToString();
15192                 for (int i=0; i<strings.size(); i++) {
15193                     if (flat.contains(strings.get(i))) {
15194                         return true;
15195                     }
15196                 }
15197             }
15198             return false;
15199         }
15200     }
15201
15202     /**
15203      * There are three things that cmd can be:
15204      *  - a flattened component name that matches an existing activity
15205      *  - the cmd arg isn't the flattened component name of an existing activity:
15206      *    dump all activity whose component contains the cmd as a substring
15207      *  - A hex number of the ActivityRecord object instance.
15208      */
15209     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15210             int opti, boolean dumpAll) {
15211         ArrayList<ActivityRecord> activities;
15212
15213         synchronized (this) {
15214             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15215         }
15216
15217         if (activities.size() <= 0) {
15218             return false;
15219         }
15220
15221         String[] newArgs = new String[args.length - opti];
15222         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15223
15224         TaskRecord lastTask = null;
15225         boolean needSep = false;
15226         for (int i=activities.size()-1; i>=0; i--) {
15227             ActivityRecord r = activities.get(i);
15228             if (needSep) {
15229                 pw.println();
15230             }
15231             needSep = true;
15232             synchronized (this) {
15233                 if (lastTask != r.task) {
15234                     lastTask = r.task;
15235                     pw.print("TASK "); pw.print(lastTask.affinity);
15236                             pw.print(" id="); pw.println(lastTask.taskId);
15237                     if (dumpAll) {
15238                         lastTask.dump(pw, "  ");
15239                     }
15240                 }
15241             }
15242             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15243         }
15244         return true;
15245     }
15246
15247     /**
15248      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15249      * there is a thread associated with the activity.
15250      */
15251     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15252             final ActivityRecord r, String[] args, boolean dumpAll) {
15253         String innerPrefix = prefix + "  ";
15254         synchronized (this) {
15255             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15256                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15257                     pw.print(" pid=");
15258                     if (r.app != null) pw.println(r.app.pid);
15259                     else pw.println("(not running)");
15260             if (dumpAll) {
15261                 r.dump(pw, innerPrefix);
15262             }
15263         }
15264         if (r.app != null && r.app.thread != null) {
15265             // flush anything that is already in the PrintWriter since the thread is going
15266             // to write to the file descriptor directly
15267             pw.flush();
15268             try {
15269                 TransferPipe tp = new TransferPipe();
15270                 try {
15271                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15272                             r.appToken, innerPrefix, args);
15273                     tp.go(fd);
15274                 } finally {
15275                     tp.kill();
15276                 }
15277             } catch (IOException e) {
15278                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15279             } catch (RemoteException e) {
15280                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15281             }
15282         }
15283     }
15284
15285     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15286             int opti, boolean dumpAll, String dumpPackage) {
15287         boolean needSep = false;
15288         boolean onlyHistory = false;
15289         boolean printedAnything = false;
15290
15291         if ("history".equals(dumpPackage)) {
15292             if (opti < args.length && "-s".equals(args[opti])) {
15293                 dumpAll = false;
15294             }
15295             onlyHistory = true;
15296             dumpPackage = null;
15297         }
15298
15299         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15300         if (!onlyHistory && dumpAll) {
15301             if (mRegisteredReceivers.size() > 0) {
15302                 boolean printed = false;
15303                 Iterator it = mRegisteredReceivers.values().iterator();
15304                 while (it.hasNext()) {
15305                     ReceiverList r = (ReceiverList)it.next();
15306                     if (dumpPackage != null && (r.app == null ||
15307                             !dumpPackage.equals(r.app.info.packageName))) {
15308                         continue;
15309                     }
15310                     if (!printed) {
15311                         pw.println("  Registered Receivers:");
15312                         needSep = true;
15313                         printed = true;
15314                         printedAnything = true;
15315                     }
15316                     pw.print("  * "); pw.println(r);
15317                     r.dump(pw, "    ");
15318                 }
15319             }
15320
15321             if (mReceiverResolver.dump(pw, needSep ?
15322                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15323                     "    ", dumpPackage, false, false)) {
15324                 needSep = true;
15325                 printedAnything = true;
15326             }
15327         }
15328
15329         for (BroadcastQueue q : mBroadcastQueues) {
15330             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15331             printedAnything |= needSep;
15332         }
15333
15334         needSep = true;
15335
15336         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15337             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15338                 if (needSep) {
15339                     pw.println();
15340                 }
15341                 needSep = true;
15342                 printedAnything = true;
15343                 pw.print("  Sticky broadcasts for user ");
15344                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15345                 StringBuilder sb = new StringBuilder(128);
15346                 for (Map.Entry<String, ArrayList<Intent>> ent
15347                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15348                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15349                     if (dumpAll) {
15350                         pw.println(":");
15351                         ArrayList<Intent> intents = ent.getValue();
15352                         final int N = intents.size();
15353                         for (int i=0; i<N; i++) {
15354                             sb.setLength(0);
15355                             sb.append("    Intent: ");
15356                             intents.get(i).toShortString(sb, false, true, false, false);
15357                             pw.println(sb.toString());
15358                             Bundle bundle = intents.get(i).getExtras();
15359                             if (bundle != null) {
15360                                 pw.print("      ");
15361                                 pw.println(bundle.toString());
15362                             }
15363                         }
15364                     } else {
15365                         pw.println("");
15366                     }
15367                 }
15368             }
15369         }
15370
15371         if (!onlyHistory && dumpAll) {
15372             pw.println();
15373             for (BroadcastQueue queue : mBroadcastQueues) {
15374                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15375                         + queue.mBroadcastsScheduled);
15376             }
15377             pw.println("  mHandler:");
15378             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15379             needSep = true;
15380             printedAnything = true;
15381         }
15382
15383         if (!printedAnything) {
15384             pw.println("  (nothing)");
15385         }
15386     }
15387
15388     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15389             int opti, boolean dumpAll, String dumpPackage) {
15390         if (mCurBroadcastStats == null) {
15391             return;
15392         }
15393
15394         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15395         final long now = SystemClock.elapsedRealtime();
15396         if (mLastBroadcastStats != null) {
15397             pw.print("  Last stats (from ");
15398             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15399             pw.print(" to ");
15400             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15401             pw.print(", ");
15402             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15403                     - mLastBroadcastStats.mStartUptime, pw);
15404             pw.println(" uptime):");
15405             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15406                 pw.println("    (nothing)");
15407             }
15408             pw.println();
15409         }
15410         pw.print("  Current stats (from ");
15411         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15412         pw.print(" to now, ");
15413         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15414                 - mCurBroadcastStats.mStartUptime, pw);
15415         pw.println(" uptime):");
15416         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15417             pw.println("    (nothing)");
15418         }
15419     }
15420
15421     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15422             int opti, boolean fullCheckin, String dumpPackage) {
15423         if (mCurBroadcastStats == null) {
15424             return;
15425         }
15426
15427         if (mLastBroadcastStats != null) {
15428             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15429             if (fullCheckin) {
15430                 mLastBroadcastStats = null;
15431                 return;
15432             }
15433         }
15434         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15435         if (fullCheckin) {
15436             mCurBroadcastStats = null;
15437         }
15438     }
15439
15440     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15441             int opti, boolean dumpAll, String dumpPackage) {
15442         boolean needSep;
15443         boolean printedAnything = false;
15444
15445         ItemMatcher matcher = new ItemMatcher();
15446         matcher.build(args, opti);
15447
15448         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15449
15450         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15451         printedAnything |= needSep;
15452
15453         if (mLaunchingProviders.size() > 0) {
15454             boolean printed = false;
15455             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15456                 ContentProviderRecord r = mLaunchingProviders.get(i);
15457                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15458                     continue;
15459                 }
15460                 if (!printed) {
15461                     if (needSep) pw.println();
15462                     needSep = true;
15463                     pw.println("  Launching content providers:");
15464                     printed = true;
15465                     printedAnything = true;
15466                 }
15467                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15468                         pw.println(r);
15469             }
15470         }
15471
15472         if (!printedAnything) {
15473             pw.println("  (nothing)");
15474         }
15475     }
15476
15477     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15478             int opti, boolean dumpAll, String dumpPackage) {
15479         boolean needSep = false;
15480         boolean printedAnything = false;
15481
15482         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15483
15484         if (mGrantedUriPermissions.size() > 0) {
15485             boolean printed = false;
15486             int dumpUid = -2;
15487             if (dumpPackage != null) {
15488                 try {
15489                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15490                             MATCH_UNINSTALLED_PACKAGES, 0);
15491                 } catch (NameNotFoundException e) {
15492                     dumpUid = -1;
15493                 }
15494             }
15495             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15496                 int uid = mGrantedUriPermissions.keyAt(i);
15497                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15498                     continue;
15499                 }
15500                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15501                 if (!printed) {
15502                     if (needSep) pw.println();
15503                     needSep = true;
15504                     pw.println("  Granted Uri Permissions:");
15505                     printed = true;
15506                     printedAnything = true;
15507                 }
15508                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15509                 for (UriPermission perm : perms.values()) {
15510                     pw.print("    "); pw.println(perm);
15511                     if (dumpAll) {
15512                         perm.dump(pw, "      ");
15513                     }
15514                 }
15515             }
15516         }
15517
15518         if (!printedAnything) {
15519             pw.println("  (nothing)");
15520         }
15521     }
15522
15523     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15524             int opti, boolean dumpAll, String dumpPackage) {
15525         boolean printed = false;
15526
15527         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15528
15529         if (mIntentSenderRecords.size() > 0) {
15530             Iterator<WeakReference<PendingIntentRecord>> it
15531                     = mIntentSenderRecords.values().iterator();
15532             while (it.hasNext()) {
15533                 WeakReference<PendingIntentRecord> ref = it.next();
15534                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15535                 if (dumpPackage != null && (rec == null
15536                         || !dumpPackage.equals(rec.key.packageName))) {
15537                     continue;
15538                 }
15539                 printed = true;
15540                 if (rec != null) {
15541                     pw.print("  * "); pw.println(rec);
15542                     if (dumpAll) {
15543                         rec.dump(pw, "    ");
15544                     }
15545                 } else {
15546                     pw.print("  * "); pw.println(ref);
15547                 }
15548             }
15549         }
15550
15551         if (!printed) {
15552             pw.println("  (nothing)");
15553         }
15554     }
15555
15556     private static final int dumpProcessList(PrintWriter pw,
15557             ActivityManagerService service, List list,
15558             String prefix, String normalLabel, String persistentLabel,
15559             String dumpPackage) {
15560         int numPers = 0;
15561         final int N = list.size()-1;
15562         for (int i=N; i>=0; i--) {
15563             ProcessRecord r = (ProcessRecord)list.get(i);
15564             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15565                 continue;
15566             }
15567             pw.println(String.format("%s%s #%2d: %s",
15568                     prefix, (r.persistent ? persistentLabel : normalLabel),
15569                     i, r.toString()));
15570             if (r.persistent) {
15571                 numPers++;
15572             }
15573         }
15574         return numPers;
15575     }
15576
15577     private static final boolean dumpProcessOomList(PrintWriter pw,
15578             ActivityManagerService service, List<ProcessRecord> origList,
15579             String prefix, String normalLabel, String persistentLabel,
15580             boolean inclDetails, String dumpPackage) {
15581
15582         ArrayList<Pair<ProcessRecord, Integer>> list
15583                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15584         for (int i=0; i<origList.size(); i++) {
15585             ProcessRecord r = origList.get(i);
15586             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15587                 continue;
15588             }
15589             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15590         }
15591
15592         if (list.size() <= 0) {
15593             return false;
15594         }
15595
15596         Comparator<Pair<ProcessRecord, Integer>> comparator
15597                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15598             @Override
15599             public int compare(Pair<ProcessRecord, Integer> object1,
15600                     Pair<ProcessRecord, Integer> object2) {
15601                 if (object1.first.setAdj != object2.first.setAdj) {
15602                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15603                 }
15604                 if (object1.first.setProcState != object2.first.setProcState) {
15605                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15606                 }
15607                 if (object1.second.intValue() != object2.second.intValue()) {
15608                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15609                 }
15610                 return 0;
15611             }
15612         };
15613
15614         Collections.sort(list, comparator);
15615
15616         final long curRealtime = SystemClock.elapsedRealtime();
15617         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15618         final long curUptime = SystemClock.uptimeMillis();
15619         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15620
15621         for (int i=list.size()-1; i>=0; i--) {
15622             ProcessRecord r = list.get(i).first;
15623             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15624             char schedGroup;
15625             switch (r.setSchedGroup) {
15626                 case ProcessList.SCHED_GROUP_BACKGROUND:
15627                     schedGroup = 'B';
15628                     break;
15629                 case ProcessList.SCHED_GROUP_DEFAULT:
15630                     schedGroup = 'F';
15631                     break;
15632                 case ProcessList.SCHED_GROUP_TOP_APP:
15633                     schedGroup = 'T';
15634                     break;
15635                 default:
15636                     schedGroup = '?';
15637                     break;
15638             }
15639             char foreground;
15640             if (r.foregroundActivities) {
15641                 foreground = 'A';
15642             } else if (r.foregroundServices) {
15643                 foreground = 'S';
15644             } else {
15645                 foreground = ' ';
15646             }
15647             String procState = ProcessList.makeProcStateString(r.curProcState);
15648             pw.print(prefix);
15649             pw.print(r.persistent ? persistentLabel : normalLabel);
15650             pw.print(" #");
15651             int num = (origList.size()-1)-list.get(i).second;
15652             if (num < 10) pw.print(' ');
15653             pw.print(num);
15654             pw.print(": ");
15655             pw.print(oomAdj);
15656             pw.print(' ');
15657             pw.print(schedGroup);
15658             pw.print('/');
15659             pw.print(foreground);
15660             pw.print('/');
15661             pw.print(procState);
15662             pw.print(" trm:");
15663             if (r.trimMemoryLevel < 10) pw.print(' ');
15664             pw.print(r.trimMemoryLevel);
15665             pw.print(' ');
15666             pw.print(r.toShortString());
15667             pw.print(" (");
15668             pw.print(r.adjType);
15669             pw.println(')');
15670             if (r.adjSource != null || r.adjTarget != null) {
15671                 pw.print(prefix);
15672                 pw.print("    ");
15673                 if (r.adjTarget instanceof ComponentName) {
15674                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15675                 } else if (r.adjTarget != null) {
15676                     pw.print(r.adjTarget.toString());
15677                 } else {
15678                     pw.print("{null}");
15679                 }
15680                 pw.print("<=");
15681                 if (r.adjSource instanceof ProcessRecord) {
15682                     pw.print("Proc{");
15683                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15684                     pw.println("}");
15685                 } else if (r.adjSource != null) {
15686                     pw.println(r.adjSource.toString());
15687                 } else {
15688                     pw.println("{null}");
15689                 }
15690             }
15691             if (inclDetails) {
15692                 pw.print(prefix);
15693                 pw.print("    ");
15694                 pw.print("oom: max="); pw.print(r.maxAdj);
15695                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15696                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15697                 pw.print(" cur="); pw.print(r.curAdj);
15698                 pw.print(" set="); pw.println(r.setAdj);
15699                 pw.print(prefix);
15700                 pw.print("    ");
15701                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15702                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15703                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15704                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15705                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15706                 pw.println();
15707                 pw.print(prefix);
15708                 pw.print("    ");
15709                 pw.print("cached="); pw.print(r.cached);
15710                 pw.print(" empty="); pw.print(r.empty);
15711                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15712
15713                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15714                     if (r.lastWakeTime != 0) {
15715                         long wtime;
15716                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15717                         synchronized (stats) {
15718                             wtime = stats.getProcessWakeTime(r.info.uid,
15719                                     r.pid, curRealtime);
15720                         }
15721                         long timeUsed = wtime - r.lastWakeTime;
15722                         pw.print(prefix);
15723                         pw.print("    ");
15724                         pw.print("keep awake over ");
15725                         TimeUtils.formatDuration(realtimeSince, pw);
15726                         pw.print(" used ");
15727                         TimeUtils.formatDuration(timeUsed, pw);
15728                         pw.print(" (");
15729                         pw.print((timeUsed*100)/realtimeSince);
15730                         pw.println("%)");
15731                     }
15732                     if (r.lastCpuTime != 0) {
15733                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15734                         pw.print(prefix);
15735                         pw.print("    ");
15736                         pw.print("run cpu over ");
15737                         TimeUtils.formatDuration(uptimeSince, pw);
15738                         pw.print(" used ");
15739                         TimeUtils.formatDuration(timeUsed, pw);
15740                         pw.print(" (");
15741                         pw.print((timeUsed*100)/uptimeSince);
15742                         pw.println("%)");
15743                     }
15744                 }
15745             }
15746         }
15747         return true;
15748     }
15749
15750     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15751             String[] args) {
15752         ArrayList<ProcessRecord> procs;
15753         synchronized (this) {
15754             if (args != null && args.length > start
15755                     && args[start].charAt(0) != '-') {
15756                 procs = new ArrayList<ProcessRecord>();
15757                 int pid = -1;
15758                 try {
15759                     pid = Integer.parseInt(args[start]);
15760                 } catch (NumberFormatException e) {
15761                 }
15762                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15763                     ProcessRecord proc = mLruProcesses.get(i);
15764                     if (proc.pid == pid) {
15765                         procs.add(proc);
15766                     } else if (allPkgs && proc.pkgList != null
15767                             && proc.pkgList.containsKey(args[start])) {
15768                         procs.add(proc);
15769                     } else if (proc.processName.equals(args[start])) {
15770                         procs.add(proc);
15771                     }
15772                 }
15773                 if (procs.size() <= 0) {
15774                     return null;
15775                 }
15776             } else {
15777                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15778             }
15779         }
15780         return procs;
15781     }
15782
15783     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15784             PrintWriter pw, String[] args) {
15785         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15786         if (procs == null) {
15787             pw.println("No process found for: " + args[0]);
15788             return;
15789         }
15790
15791         long uptime = SystemClock.uptimeMillis();
15792         long realtime = SystemClock.elapsedRealtime();
15793         pw.println("Applications Graphics Acceleration Info:");
15794         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15795
15796         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15797             ProcessRecord r = procs.get(i);
15798             if (r.thread != null) {
15799                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15800                 pw.flush();
15801                 try {
15802                     TransferPipe tp = new TransferPipe();
15803                     try {
15804                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15805                         tp.go(fd);
15806                     } finally {
15807                         tp.kill();
15808                     }
15809                 } catch (IOException e) {
15810                     pw.println("Failure while dumping the app: " + r);
15811                     pw.flush();
15812                 } catch (RemoteException e) {
15813                     pw.println("Got a RemoteException while dumping the app " + r);
15814                     pw.flush();
15815                 }
15816             }
15817         }
15818     }
15819
15820     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15821         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15822         if (procs == null) {
15823             pw.println("No process found for: " + args[0]);
15824             return;
15825         }
15826
15827         pw.println("Applications Database Info:");
15828
15829         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15830             ProcessRecord r = procs.get(i);
15831             if (r.thread != null) {
15832                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15833                 pw.flush();
15834                 try {
15835                     TransferPipe tp = new TransferPipe();
15836                     try {
15837                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15838                         tp.go(fd);
15839                     } finally {
15840                         tp.kill();
15841                     }
15842                 } catch (IOException e) {
15843                     pw.println("Failure while dumping the app: " + r);
15844                     pw.flush();
15845                 } catch (RemoteException e) {
15846                     pw.println("Got a RemoteException while dumping the app " + r);
15847                     pw.flush();
15848                 }
15849             }
15850         }
15851     }
15852
15853     final static class MemItem {
15854         final boolean isProc;
15855         final String label;
15856         final String shortLabel;
15857         final long pss;
15858         final long swapPss;
15859         final int id;
15860         final boolean hasActivities;
15861         ArrayList<MemItem> subitems;
15862
15863         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15864                 boolean _hasActivities) {
15865             isProc = true;
15866             label = _label;
15867             shortLabel = _shortLabel;
15868             pss = _pss;
15869             swapPss = _swapPss;
15870             id = _id;
15871             hasActivities = _hasActivities;
15872         }
15873
15874         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15875             isProc = false;
15876             label = _label;
15877             shortLabel = _shortLabel;
15878             pss = _pss;
15879             swapPss = _swapPss;
15880             id = _id;
15881             hasActivities = false;
15882         }
15883     }
15884
15885     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15886             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15887         if (sort && !isCompact) {
15888             Collections.sort(items, new Comparator<MemItem>() {
15889                 @Override
15890                 public int compare(MemItem lhs, MemItem rhs) {
15891                     if (lhs.pss < rhs.pss) {
15892                         return 1;
15893                     } else if (lhs.pss > rhs.pss) {
15894                         return -1;
15895                     }
15896                     return 0;
15897                 }
15898             });
15899         }
15900
15901         for (int i=0; i<items.size(); i++) {
15902             MemItem mi = items.get(i);
15903             if (!isCompact) {
15904                 if (dumpSwapPss) {
15905                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15906                             mi.label, stringifyKBSize(mi.swapPss));
15907                 } else {
15908                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15909                 }
15910             } else if (mi.isProc) {
15911                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15912                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15913                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15914                 pw.println(mi.hasActivities ? ",a" : ",e");
15915             } else {
15916                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15917                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15918             }
15919             if (mi.subitems != null) {
15920                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15921                         true, isCompact, dumpSwapPss);
15922             }
15923         }
15924     }
15925
15926     // These are in KB.
15927     static final long[] DUMP_MEM_BUCKETS = new long[] {
15928         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15929         120*1024, 160*1024, 200*1024,
15930         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15931         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15932     };
15933
15934     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15935             boolean stackLike) {
15936         int start = label.lastIndexOf('.');
15937         if (start >= 0) start++;
15938         else start = 0;
15939         int end = label.length();
15940         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15941             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15942                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15943                 out.append(bucket);
15944                 out.append(stackLike ? "MB." : "MB ");
15945                 out.append(label, start, end);
15946                 return;
15947             }
15948         }
15949         out.append(memKB/1024);
15950         out.append(stackLike ? "MB." : "MB ");
15951         out.append(label, start, end);
15952     }
15953
15954     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15955             ProcessList.NATIVE_ADJ,
15956             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15957             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15958             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15959             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15960             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15961             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15962     };
15963     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15964             "Native",
15965             "System", "Persistent", "Persistent Service", "Foreground",
15966             "Visible", "Perceptible",
15967             "Heavy Weight", "Backup",
15968             "A Services", "Home",
15969             "Previous", "B Services", "Cached"
15970     };
15971     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15972             "native",
15973             "sys", "pers", "persvc", "fore",
15974             "vis", "percept",
15975             "heavy", "backup",
15976             "servicea", "home",
15977             "prev", "serviceb", "cached"
15978     };
15979
15980     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15981             long realtime, boolean isCheckinRequest, boolean isCompact) {
15982         if (isCompact) {
15983             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15984         }
15985         if (isCheckinRequest || isCompact) {
15986             // short checkin version
15987             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15988         } else {
15989             pw.println("Applications Memory Usage (in Kilobytes):");
15990             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15991         }
15992     }
15993
15994     private static final int KSM_SHARED = 0;
15995     private static final int KSM_SHARING = 1;
15996     private static final int KSM_UNSHARED = 2;
15997     private static final int KSM_VOLATILE = 3;
15998
15999     private final long[] getKsmInfo() {
16000         long[] longOut = new long[4];
16001         final int[] SINGLE_LONG_FORMAT = new int[] {
16002             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16003         };
16004         long[] longTmp = new long[1];
16005         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16006                 SINGLE_LONG_FORMAT, null, longTmp, null);
16007         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16008         longTmp[0] = 0;
16009         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16010                 SINGLE_LONG_FORMAT, null, longTmp, null);
16011         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16012         longTmp[0] = 0;
16013         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16014                 SINGLE_LONG_FORMAT, null, longTmp, null);
16015         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16016         longTmp[0] = 0;
16017         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16018                 SINGLE_LONG_FORMAT, null, longTmp, null);
16019         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16020         return longOut;
16021     }
16022
16023     private static String stringifySize(long size, int order) {
16024         Locale locale = Locale.US;
16025         switch (order) {
16026             case 1:
16027                 return String.format(locale, "%,13d", size);
16028             case 1024:
16029                 return String.format(locale, "%,9dK", size / 1024);
16030             case 1024 * 1024:
16031                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16032             case 1024 * 1024 * 1024:
16033                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16034             default:
16035                 throw new IllegalArgumentException("Invalid size order");
16036         }
16037     }
16038
16039     private static String stringifyKBSize(long size) {
16040         return stringifySize(size * 1024, 1024);
16041     }
16042
16043     // Update this version number in case you change the 'compact' format
16044     private static final int MEMINFO_COMPACT_VERSION = 1;
16045
16046     final void dumpApplicationMemoryUsage(FileDescriptor fd,
16047             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16048         boolean dumpDetails = false;
16049         boolean dumpFullDetails = false;
16050         boolean dumpDalvik = false;
16051         boolean dumpSummaryOnly = false;
16052         boolean dumpUnreachable = false;
16053         boolean oomOnly = false;
16054         boolean isCompact = false;
16055         boolean localOnly = false;
16056         boolean packages = false;
16057         boolean isCheckinRequest = false;
16058         boolean dumpSwapPss = false;
16059
16060         int opti = 0;
16061         while (opti < args.length) {
16062             String opt = args[opti];
16063             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16064                 break;
16065             }
16066             opti++;
16067             if ("-a".equals(opt)) {
16068                 dumpDetails = true;
16069                 dumpFullDetails = true;
16070                 dumpDalvik = true;
16071                 dumpSwapPss = true;
16072             } else if ("-d".equals(opt)) {
16073                 dumpDalvik = true;
16074             } else if ("-c".equals(opt)) {
16075                 isCompact = true;
16076             } else if ("-s".equals(opt)) {
16077                 dumpDetails = true;
16078                 dumpSummaryOnly = true;
16079             } else if ("-S".equals(opt)) {
16080                 dumpSwapPss = true;
16081             } else if ("--unreachable".equals(opt)) {
16082                 dumpUnreachable = true;
16083             } else if ("--oom".equals(opt)) {
16084                 oomOnly = true;
16085             } else if ("--local".equals(opt)) {
16086                 localOnly = true;
16087             } else if ("--package".equals(opt)) {
16088                 packages = true;
16089             } else if ("--checkin".equals(opt)) {
16090                 isCheckinRequest = true;
16091
16092             } else if ("-h".equals(opt)) {
16093                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16094                 pw.println("  -a: include all available information for each process.");
16095                 pw.println("  -d: include dalvik details.");
16096                 pw.println("  -c: dump in a compact machine-parseable representation.");
16097                 pw.println("  -s: dump only summary of application memory usage.");
16098                 pw.println("  -S: dump also SwapPss.");
16099                 pw.println("  --oom: only show processes organized by oom adj.");
16100                 pw.println("  --local: only collect details locally, don't call process.");
16101                 pw.println("  --package: interpret process arg as package, dumping all");
16102                 pw.println("             processes that have loaded that package.");
16103                 pw.println("  --checkin: dump data for a checkin");
16104                 pw.println("If [process] is specified it can be the name or ");
16105                 pw.println("pid of a specific process to dump.");
16106                 return;
16107             } else {
16108                 pw.println("Unknown argument: " + opt + "; use -h for help");
16109             }
16110         }
16111
16112         long uptime = SystemClock.uptimeMillis();
16113         long realtime = SystemClock.elapsedRealtime();
16114         final long[] tmpLong = new long[1];
16115
16116         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16117         if (procs == null) {
16118             // No Java processes.  Maybe they want to print a native process.
16119             if (args != null && args.length > opti
16120                     && args[opti].charAt(0) != '-') {
16121                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16122                         = new ArrayList<ProcessCpuTracker.Stats>();
16123                 updateCpuStatsNow();
16124                 int findPid = -1;
16125                 try {
16126                     findPid = Integer.parseInt(args[opti]);
16127                 } catch (NumberFormatException e) {
16128                 }
16129                 synchronized (mProcessCpuTracker) {
16130                     final int N = mProcessCpuTracker.countStats();
16131                     for (int i=0; i<N; i++) {
16132                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16133                         if (st.pid == findPid || (st.baseName != null
16134                                 && st.baseName.equals(args[opti]))) {
16135                             nativeProcs.add(st);
16136                         }
16137                     }
16138                 }
16139                 if (nativeProcs.size() > 0) {
16140                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16141                             isCompact);
16142                     Debug.MemoryInfo mi = null;
16143                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16144                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16145                         final int pid = r.pid;
16146                         if (!isCheckinRequest && dumpDetails) {
16147                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16148                         }
16149                         if (mi == null) {
16150                             mi = new Debug.MemoryInfo();
16151                         }
16152                         if (dumpDetails || (!brief && !oomOnly)) {
16153                             Debug.getMemoryInfo(pid, mi);
16154                         } else {
16155                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16156                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16157                         }
16158                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16159                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16160                         if (isCheckinRequest) {
16161                             pw.println();
16162                         }
16163                     }
16164                     return;
16165                 }
16166             }
16167             pw.println("No process found for: " + args[opti]);
16168             return;
16169         }
16170
16171         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16172             dumpDetails = true;
16173         }
16174
16175         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16176
16177         String[] innerArgs = new String[args.length-opti];
16178         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16179
16180         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16181         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16182         long nativePss = 0;
16183         long nativeSwapPss = 0;
16184         long dalvikPss = 0;
16185         long dalvikSwapPss = 0;
16186         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16187                 EmptyArray.LONG;
16188         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16189                 EmptyArray.LONG;
16190         long otherPss = 0;
16191         long otherSwapPss = 0;
16192         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16193         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16194
16195         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16196         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16197         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16198                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16199
16200         long totalPss = 0;
16201         long totalSwapPss = 0;
16202         long cachedPss = 0;
16203         long cachedSwapPss = 0;
16204         boolean hasSwapPss = false;
16205
16206         Debug.MemoryInfo mi = null;
16207         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16208             final ProcessRecord r = procs.get(i);
16209             final IApplicationThread thread;
16210             final int pid;
16211             final int oomAdj;
16212             final boolean hasActivities;
16213             synchronized (this) {
16214                 thread = r.thread;
16215                 pid = r.pid;
16216                 oomAdj = r.getSetAdjWithServices();
16217                 hasActivities = r.activities.size() > 0;
16218             }
16219             if (thread != null) {
16220                 if (!isCheckinRequest && dumpDetails) {
16221                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16222                 }
16223                 if (mi == null) {
16224                     mi = new Debug.MemoryInfo();
16225                 }
16226                 if (dumpDetails || (!brief && !oomOnly)) {
16227                     Debug.getMemoryInfo(pid, mi);
16228                     hasSwapPss = mi.hasSwappedOutPss;
16229                 } else {
16230                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16231                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16232                 }
16233                 if (dumpDetails) {
16234                     if (localOnly) {
16235                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16236                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16237                         if (isCheckinRequest) {
16238                             pw.println();
16239                         }
16240                     } else {
16241                         try {
16242                             pw.flush();
16243                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16244                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16245                         } catch (RemoteException e) {
16246                             if (!isCheckinRequest) {
16247                                 pw.println("Got RemoteException!");
16248                                 pw.flush();
16249                             }
16250                         }
16251                     }
16252                 }
16253
16254                 final long myTotalPss = mi.getTotalPss();
16255                 final long myTotalUss = mi.getTotalUss();
16256                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16257
16258                 synchronized (this) {
16259                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16260                         // Record this for posterity if the process has been stable.
16261                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16262                     }
16263                 }
16264
16265                 if (!isCheckinRequest && mi != null) {
16266                     totalPss += myTotalPss;
16267                     totalSwapPss += myTotalSwapPss;
16268                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16269                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16270                             myTotalSwapPss, pid, hasActivities);
16271                     procMems.add(pssItem);
16272                     procMemsMap.put(pid, pssItem);
16273
16274                     nativePss += mi.nativePss;
16275                     nativeSwapPss += mi.nativeSwappedOutPss;
16276                     dalvikPss += mi.dalvikPss;
16277                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16278                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16279                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16280                         dalvikSubitemSwapPss[j] +=
16281                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16282                     }
16283                     otherPss += mi.otherPss;
16284                     otherSwapPss += mi.otherSwappedOutPss;
16285                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16286                         long mem = mi.getOtherPss(j);
16287                         miscPss[j] += mem;
16288                         otherPss -= mem;
16289                         mem = mi.getOtherSwappedOutPss(j);
16290                         miscSwapPss[j] += mem;
16291                         otherSwapPss -= mem;
16292                     }
16293
16294                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16295                         cachedPss += myTotalPss;
16296                         cachedSwapPss += myTotalSwapPss;
16297                     }
16298
16299                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16300                         if (oomIndex == (oomPss.length - 1)
16301                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16302                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16303                             oomPss[oomIndex] += myTotalPss;
16304                             oomSwapPss[oomIndex] += myTotalSwapPss;
16305                             if (oomProcs[oomIndex] == null) {
16306                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16307                             }
16308                             oomProcs[oomIndex].add(pssItem);
16309                             break;
16310                         }
16311                     }
16312                 }
16313             }
16314         }
16315
16316         long nativeProcTotalPss = 0;
16317
16318         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16319             // If we are showing aggregations, also look for native processes to
16320             // include so that our aggregations are more accurate.
16321             updateCpuStatsNow();
16322             mi = null;
16323             synchronized (mProcessCpuTracker) {
16324                 final int N = mProcessCpuTracker.countStats();
16325                 for (int i=0; i<N; i++) {
16326                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16327                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16328                         if (mi == null) {
16329                             mi = new Debug.MemoryInfo();
16330                         }
16331                         if (!brief && !oomOnly) {
16332                             Debug.getMemoryInfo(st.pid, mi);
16333                         } else {
16334                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16335                             mi.nativePrivateDirty = (int)tmpLong[0];
16336                         }
16337
16338                         final long myTotalPss = mi.getTotalPss();
16339                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16340                         totalPss += myTotalPss;
16341                         nativeProcTotalPss += myTotalPss;
16342
16343                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16344                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16345                         procMems.add(pssItem);
16346
16347                         nativePss += mi.nativePss;
16348                         nativeSwapPss += mi.nativeSwappedOutPss;
16349                         dalvikPss += mi.dalvikPss;
16350                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16351                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16352                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16353                             dalvikSubitemSwapPss[j] +=
16354                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16355                         }
16356                         otherPss += mi.otherPss;
16357                         otherSwapPss += mi.otherSwappedOutPss;
16358                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16359                             long mem = mi.getOtherPss(j);
16360                             miscPss[j] += mem;
16361                             otherPss -= mem;
16362                             mem = mi.getOtherSwappedOutPss(j);
16363                             miscSwapPss[j] += mem;
16364                             otherSwapPss -= mem;
16365                         }
16366                         oomPss[0] += myTotalPss;
16367                         oomSwapPss[0] += myTotalSwapPss;
16368                         if (oomProcs[0] == null) {
16369                             oomProcs[0] = new ArrayList<MemItem>();
16370                         }
16371                         oomProcs[0].add(pssItem);
16372                     }
16373                 }
16374             }
16375
16376             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16377
16378             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16379             final MemItem dalvikItem =
16380                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16381             if (dalvikSubitemPss.length > 0) {
16382                 dalvikItem.subitems = new ArrayList<MemItem>();
16383                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16384                     final String name = Debug.MemoryInfo.getOtherLabel(
16385                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16386                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16387                                     dalvikSubitemSwapPss[j], j));
16388                 }
16389             }
16390             catMems.add(dalvikItem);
16391             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16392             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16393                 String label = Debug.MemoryInfo.getOtherLabel(j);
16394                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16395             }
16396
16397             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16398             for (int j=0; j<oomPss.length; j++) {
16399                 if (oomPss[j] != 0) {
16400                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16401                             : DUMP_MEM_OOM_LABEL[j];
16402                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16403                             DUMP_MEM_OOM_ADJ[j]);
16404                     item.subitems = oomProcs[j];
16405                     oomMems.add(item);
16406                 }
16407             }
16408
16409             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16410             if (!brief && !oomOnly && !isCompact) {
16411                 pw.println();
16412                 pw.println("Total PSS by process:");
16413                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16414                 pw.println();
16415             }
16416             if (!isCompact) {
16417                 pw.println("Total PSS by OOM adjustment:");
16418             }
16419             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16420             if (!brief && !oomOnly) {
16421                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16422                 if (!isCompact) {
16423                     out.println();
16424                     out.println("Total PSS by category:");
16425                 }
16426                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16427             }
16428             if (!isCompact) {
16429                 pw.println();
16430             }
16431             MemInfoReader memInfo = new MemInfoReader();
16432             memInfo.readMemInfo();
16433             if (nativeProcTotalPss > 0) {
16434                 synchronized (this) {
16435                     final long cachedKb = memInfo.getCachedSizeKb();
16436                     final long freeKb = memInfo.getFreeSizeKb();
16437                     final long zramKb = memInfo.getZramTotalSizeKb();
16438                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16439                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16440                             kernelKb*1024, nativeProcTotalPss*1024);
16441                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16442                             nativeProcTotalPss);
16443                 }
16444             }
16445             if (!brief) {
16446                 if (!isCompact) {
16447                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16448                     pw.print(" (status ");
16449                     switch (mLastMemoryLevel) {
16450                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16451                             pw.println("normal)");
16452                             break;
16453                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16454                             pw.println("moderate)");
16455                             break;
16456                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16457                             pw.println("low)");
16458                             break;
16459                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16460                             pw.println("critical)");
16461                             break;
16462                         default:
16463                             pw.print(mLastMemoryLevel);
16464                             pw.println(")");
16465                             break;
16466                     }
16467                     pw.print(" Free RAM: ");
16468                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16469                             + memInfo.getFreeSizeKb()));
16470                     pw.print(" (");
16471                     pw.print(stringifyKBSize(cachedPss));
16472                     pw.print(" cached pss + ");
16473                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16474                     pw.print(" cached kernel + ");
16475                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16476                     pw.println(" free)");
16477                 } else {
16478                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16479                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16480                             + memInfo.getFreeSizeKb()); pw.print(",");
16481                     pw.println(totalPss - cachedPss);
16482                 }
16483             }
16484             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16485                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16486                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16487             if (!isCompact) {
16488                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16489                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16490                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16491                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16492                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16493             } else {
16494                 pw.print("lostram,"); pw.println(lostRAM);
16495             }
16496             if (!brief) {
16497                 if (memInfo.getZramTotalSizeKb() != 0) {
16498                     if (!isCompact) {
16499                         pw.print("     ZRAM: ");
16500                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16501                                 pw.print(" physical used for ");
16502                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16503                                         - memInfo.getSwapFreeSizeKb()));
16504                                 pw.print(" in swap (");
16505                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16506                                 pw.println(" total swap)");
16507                     } else {
16508                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16509                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16510                                 pw.println(memInfo.getSwapFreeSizeKb());
16511                     }
16512                 }
16513                 final long[] ksm = getKsmInfo();
16514                 if (!isCompact) {
16515                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16516                             || ksm[KSM_VOLATILE] != 0) {
16517                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16518                                 pw.print(" saved from shared ");
16519                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16520                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16521                                 pw.print(" unshared; ");
16522                                 pw.print(stringifyKBSize(
16523                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16524                     }
16525                     pw.print("   Tuning: ");
16526                     pw.print(ActivityManager.staticGetMemoryClass());
16527                     pw.print(" (large ");
16528                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16529                     pw.print("), oom ");
16530                     pw.print(stringifySize(
16531                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16532                     pw.print(", restore limit ");
16533                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16534                     if (ActivityManager.isLowRamDeviceStatic()) {
16535                         pw.print(" (low-ram)");
16536                     }
16537                     if (ActivityManager.isHighEndGfx()) {
16538                         pw.print(" (high-end-gfx)");
16539                     }
16540                     pw.println();
16541                 } else {
16542                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16543                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16544                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16545                     pw.print("tuning,");
16546                     pw.print(ActivityManager.staticGetMemoryClass());
16547                     pw.print(',');
16548                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16549                     pw.print(',');
16550                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16551                     if (ActivityManager.isLowRamDeviceStatic()) {
16552                         pw.print(",low-ram");
16553                     }
16554                     if (ActivityManager.isHighEndGfx()) {
16555                         pw.print(",high-end-gfx");
16556                     }
16557                     pw.println();
16558                 }
16559             }
16560         }
16561     }
16562
16563     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16564             long memtrack, String name) {
16565         sb.append("  ");
16566         sb.append(ProcessList.makeOomAdjString(oomAdj));
16567         sb.append(' ');
16568         sb.append(ProcessList.makeProcStateString(procState));
16569         sb.append(' ');
16570         ProcessList.appendRamKb(sb, pss);
16571         sb.append(": ");
16572         sb.append(name);
16573         if (memtrack > 0) {
16574             sb.append(" (");
16575             sb.append(stringifyKBSize(memtrack));
16576             sb.append(" memtrack)");
16577         }
16578     }
16579
16580     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16581         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16582         sb.append(" (pid ");
16583         sb.append(mi.pid);
16584         sb.append(") ");
16585         sb.append(mi.adjType);
16586         sb.append('\n');
16587         if (mi.adjReason != null) {
16588             sb.append("                      ");
16589             sb.append(mi.adjReason);
16590             sb.append('\n');
16591         }
16592     }
16593
16594     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16595         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16596         for (int i=0, N=memInfos.size(); i<N; i++) {
16597             ProcessMemInfo mi = memInfos.get(i);
16598             infoMap.put(mi.pid, mi);
16599         }
16600         updateCpuStatsNow();
16601         long[] memtrackTmp = new long[1];
16602         final List<ProcessCpuTracker.Stats> stats;
16603         // Get a list of Stats that have vsize > 0
16604         synchronized (mProcessCpuTracker) {
16605             stats = mProcessCpuTracker.getStats((st) -> {
16606                 return st.vsize > 0;
16607             });
16608         }
16609         final int statsCount = stats.size();
16610         for (int i = 0; i < statsCount; i++) {
16611             ProcessCpuTracker.Stats st = stats.get(i);
16612             long pss = Debug.getPss(st.pid, null, memtrackTmp);
16613             if (pss > 0) {
16614                 if (infoMap.indexOfKey(st.pid) < 0) {
16615                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16616                             ProcessList.NATIVE_ADJ, -1, "native", null);
16617                     mi.pss = pss;
16618                     mi.memtrack = memtrackTmp[0];
16619                     memInfos.add(mi);
16620                 }
16621             }
16622         }
16623
16624         long totalPss = 0;
16625         long totalMemtrack = 0;
16626         for (int i=0, N=memInfos.size(); i<N; i++) {
16627             ProcessMemInfo mi = memInfos.get(i);
16628             if (mi.pss == 0) {
16629                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16630                 mi.memtrack = memtrackTmp[0];
16631             }
16632             totalPss += mi.pss;
16633             totalMemtrack += mi.memtrack;
16634         }
16635         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16636             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16637                 if (lhs.oomAdj != rhs.oomAdj) {
16638                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16639                 }
16640                 if (lhs.pss != rhs.pss) {
16641                     return lhs.pss < rhs.pss ? 1 : -1;
16642                 }
16643                 return 0;
16644             }
16645         });
16646
16647         StringBuilder tag = new StringBuilder(128);
16648         StringBuilder stack = new StringBuilder(128);
16649         tag.append("Low on memory -- ");
16650         appendMemBucket(tag, totalPss, "total", false);
16651         appendMemBucket(stack, totalPss, "total", true);
16652
16653         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16654         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16655         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16656
16657         boolean firstLine = true;
16658         int lastOomAdj = Integer.MIN_VALUE;
16659         long extraNativeRam = 0;
16660         long extraNativeMemtrack = 0;
16661         long cachedPss = 0;
16662         for (int i=0, N=memInfos.size(); i<N; i++) {
16663             ProcessMemInfo mi = memInfos.get(i);
16664
16665             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16666                 cachedPss += mi.pss;
16667             }
16668
16669             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16670                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16671                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16672                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16673                 if (lastOomAdj != mi.oomAdj) {
16674                     lastOomAdj = mi.oomAdj;
16675                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16676                         tag.append(" / ");
16677                     }
16678                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16679                         if (firstLine) {
16680                             stack.append(":");
16681                             firstLine = false;
16682                         }
16683                         stack.append("\n\t at ");
16684                     } else {
16685                         stack.append("$");
16686                     }
16687                 } else {
16688                     tag.append(" ");
16689                     stack.append("$");
16690                 }
16691                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16692                     appendMemBucket(tag, mi.pss, mi.name, false);
16693                 }
16694                 appendMemBucket(stack, mi.pss, mi.name, true);
16695                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16696                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16697                     stack.append("(");
16698                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16699                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16700                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16701                             stack.append(":");
16702                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16703                         }
16704                     }
16705                     stack.append(")");
16706                 }
16707             }
16708
16709             appendMemInfo(fullNativeBuilder, mi);
16710             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16711                 // The short form only has native processes that are >= 512K.
16712                 if (mi.pss >= 512) {
16713                     appendMemInfo(shortNativeBuilder, mi);
16714                 } else {
16715                     extraNativeRam += mi.pss;
16716                     extraNativeMemtrack += mi.memtrack;
16717                 }
16718             } else {
16719                 // Short form has all other details, but if we have collected RAM
16720                 // from smaller native processes let's dump a summary of that.
16721                 if (extraNativeRam > 0) {
16722                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16723                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16724                     shortNativeBuilder.append('\n');
16725                     extraNativeRam = 0;
16726                 }
16727                 appendMemInfo(fullJavaBuilder, mi);
16728             }
16729         }
16730
16731         fullJavaBuilder.append("           ");
16732         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16733         fullJavaBuilder.append(": TOTAL");
16734         if (totalMemtrack > 0) {
16735             fullJavaBuilder.append(" (");
16736             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16737             fullJavaBuilder.append(" memtrack)");
16738         } else {
16739         }
16740         fullJavaBuilder.append("\n");
16741
16742         MemInfoReader memInfo = new MemInfoReader();
16743         memInfo.readMemInfo();
16744         final long[] infos = memInfo.getRawInfo();
16745
16746         StringBuilder memInfoBuilder = new StringBuilder(1024);
16747         Debug.getMemInfo(infos);
16748         memInfoBuilder.append("  MemInfo: ");
16749         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16750         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16751         memInfoBuilder.append(stringifyKBSize(
16752                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16753         memInfoBuilder.append(stringifyKBSize(
16754                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16755         memInfoBuilder.append(stringifyKBSize(
16756                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16757         memInfoBuilder.append("           ");
16758         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16759         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16760         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16761         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16762         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16763             memInfoBuilder.append("  ZRAM: ");
16764             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16765             memInfoBuilder.append(" RAM, ");
16766             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16767             memInfoBuilder.append(" swap total, ");
16768             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16769             memInfoBuilder.append(" swap free\n");
16770         }
16771         final long[] ksm = getKsmInfo();
16772         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16773                 || ksm[KSM_VOLATILE] != 0) {
16774             memInfoBuilder.append("  KSM: ");
16775             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16776             memInfoBuilder.append(" saved from shared ");
16777             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16778             memInfoBuilder.append("\n       ");
16779             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16780             memInfoBuilder.append(" unshared; ");
16781             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16782             memInfoBuilder.append(" volatile\n");
16783         }
16784         memInfoBuilder.append("  Free RAM: ");
16785         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16786                 + memInfo.getFreeSizeKb()));
16787         memInfoBuilder.append("\n");
16788         memInfoBuilder.append("  Used RAM: ");
16789         memInfoBuilder.append(stringifyKBSize(
16790                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16791         memInfoBuilder.append("\n");
16792         memInfoBuilder.append("  Lost RAM: ");
16793         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16794                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16795                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16796         memInfoBuilder.append("\n");
16797         Slog.i(TAG, "Low on memory:");
16798         Slog.i(TAG, shortNativeBuilder.toString());
16799         Slog.i(TAG, fullJavaBuilder.toString());
16800         Slog.i(TAG, memInfoBuilder.toString());
16801
16802         StringBuilder dropBuilder = new StringBuilder(1024);
16803         /*
16804         StringWriter oomSw = new StringWriter();
16805         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16806         StringWriter catSw = new StringWriter();
16807         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16808         String[] emptyArgs = new String[] { };
16809         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16810         oomPw.flush();
16811         String oomString = oomSw.toString();
16812         */
16813         dropBuilder.append("Low on memory:");
16814         dropBuilder.append(stack);
16815         dropBuilder.append('\n');
16816         dropBuilder.append(fullNativeBuilder);
16817         dropBuilder.append(fullJavaBuilder);
16818         dropBuilder.append('\n');
16819         dropBuilder.append(memInfoBuilder);
16820         dropBuilder.append('\n');
16821         /*
16822         dropBuilder.append(oomString);
16823         dropBuilder.append('\n');
16824         */
16825         StringWriter catSw = new StringWriter();
16826         synchronized (ActivityManagerService.this) {
16827             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16828             String[] emptyArgs = new String[] { };
16829             catPw.println();
16830             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16831             catPw.println();
16832             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16833                     false, null).dumpLocked();
16834             catPw.println();
16835             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16836             catPw.flush();
16837         }
16838         dropBuilder.append(catSw.toString());
16839         addErrorToDropBox("lowmem", null, "system_server", null,
16840                 null, tag.toString(), dropBuilder.toString(), null, null);
16841         //Slog.i(TAG, "Sent to dropbox:");
16842         //Slog.i(TAG, dropBuilder.toString());
16843         synchronized (ActivityManagerService.this) {
16844             long now = SystemClock.uptimeMillis();
16845             if (mLastMemUsageReportTime < now) {
16846                 mLastMemUsageReportTime = now;
16847             }
16848         }
16849     }
16850
16851     /**
16852      * Searches array of arguments for the specified string
16853      * @param args array of argument strings
16854      * @param value value to search for
16855      * @return true if the value is contained in the array
16856      */
16857     private static boolean scanArgs(String[] args, String value) {
16858         if (args != null) {
16859             for (String arg : args) {
16860                 if (value.equals(arg)) {
16861                     return true;
16862                 }
16863             }
16864         }
16865         return false;
16866     }
16867
16868     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16869             ContentProviderRecord cpr, boolean always) {
16870         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16871
16872         if (!inLaunching || always) {
16873             synchronized (cpr) {
16874                 cpr.launchingApp = null;
16875                 cpr.notifyAll();
16876             }
16877             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16878             String names[] = cpr.info.authority.split(";");
16879             for (int j = 0; j < names.length; j++) {
16880                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16881             }
16882         }
16883
16884         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16885             ContentProviderConnection conn = cpr.connections.get(i);
16886             if (conn.waiting) {
16887                 // If this connection is waiting for the provider, then we don't
16888                 // need to mess with its process unless we are always removing
16889                 // or for some reason the provider is not currently launching.
16890                 if (inLaunching && !always) {
16891                     continue;
16892                 }
16893             }
16894             ProcessRecord capp = conn.client;
16895             conn.dead = true;
16896             if (conn.stableCount > 0) {
16897                 if (!capp.persistent && capp.thread != null
16898                         && capp.pid != 0
16899                         && capp.pid != MY_PID) {
16900                     capp.kill("depends on provider "
16901                             + cpr.name.flattenToShortString()
16902                             + " in dying proc " + (proc != null ? proc.processName : "??")
16903                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16904                 }
16905             } else if (capp.thread != null && conn.provider.provider != null) {
16906                 try {
16907                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16908                 } catch (RemoteException e) {
16909                 }
16910                 // In the protocol here, we don't expect the client to correctly
16911                 // clean up this connection, we'll just remove it.
16912                 cpr.connections.remove(i);
16913                 if (conn.client.conProviders.remove(conn)) {
16914                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16915                 }
16916             }
16917         }
16918
16919         if (inLaunching && always) {
16920             mLaunchingProviders.remove(cpr);
16921         }
16922         return inLaunching;
16923     }
16924
16925     /**
16926      * Main code for cleaning up a process when it has gone away.  This is
16927      * called both as a result of the process dying, or directly when stopping
16928      * a process when running in single process mode.
16929      *
16930      * @return Returns true if the given process has been restarted, so the
16931      * app that was passed in must remain on the process lists.
16932      */
16933     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16934             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16935         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16936         if (index >= 0) {
16937             removeLruProcessLocked(app);
16938             ProcessList.remove(app.pid);
16939         }
16940
16941         mProcessesToGc.remove(app);
16942         mPendingPssProcesses.remove(app);
16943
16944         // Dismiss any open dialogs.
16945         if (app.crashDialog != null && !app.forceCrashReport) {
16946             app.crashDialog.dismiss();
16947             app.crashDialog = null;
16948         }
16949         if (app.anrDialog != null) {
16950             app.anrDialog.dismiss();
16951             app.anrDialog = null;
16952         }
16953         if (app.waitDialog != null) {
16954             app.waitDialog.dismiss();
16955             app.waitDialog = null;
16956         }
16957
16958         app.crashing = false;
16959         app.notResponding = false;
16960
16961         app.resetPackageList(mProcessStats);
16962         app.unlinkDeathRecipient();
16963         app.makeInactive(mProcessStats);
16964         app.waitingToKill = null;
16965         app.forcingToForeground = null;
16966         updateProcessForegroundLocked(app, false, false);
16967         app.foregroundActivities = false;
16968         app.hasShownUi = false;
16969         app.treatLikeActivity = false;
16970         app.hasAboveClient = false;
16971         app.hasClientActivities = false;
16972
16973         mServices.killServicesLocked(app, allowRestart);
16974
16975         boolean restart = false;
16976
16977         // Remove published content providers.
16978         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16979             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16980             final boolean always = app.bad || !allowRestart;
16981             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16982             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16983                 // We left the provider in the launching list, need to
16984                 // restart it.
16985                 restart = true;
16986             }
16987
16988             cpr.provider = null;
16989             cpr.proc = null;
16990         }
16991         app.pubProviders.clear();
16992
16993         // Take care of any launching providers waiting for this process.
16994         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16995             restart = true;
16996         }
16997
16998         // Unregister from connected content providers.
16999         if (!app.conProviders.isEmpty()) {
17000             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17001                 ContentProviderConnection conn = app.conProviders.get(i);
17002                 conn.provider.connections.remove(conn);
17003                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17004                         conn.provider.name);
17005             }
17006             app.conProviders.clear();
17007         }
17008
17009         // At this point there may be remaining entries in mLaunchingProviders
17010         // where we were the only one waiting, so they are no longer of use.
17011         // Look for these and clean up if found.
17012         // XXX Commented out for now.  Trying to figure out a way to reproduce
17013         // the actual situation to identify what is actually going on.
17014         if (false) {
17015             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17016                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17017                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17018                     synchronized (cpr) {
17019                         cpr.launchingApp = null;
17020                         cpr.notifyAll();
17021                     }
17022                 }
17023             }
17024         }
17025
17026         skipCurrentReceiverLocked(app);
17027
17028         // Unregister any receivers.
17029         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17030             removeReceiverLocked(app.receivers.valueAt(i));
17031         }
17032         app.receivers.clear();
17033
17034         // If the app is undergoing backup, tell the backup manager about it
17035         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17036             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17037                     + mBackupTarget.appInfo + " died during backup");
17038             try {
17039                 IBackupManager bm = IBackupManager.Stub.asInterface(
17040                         ServiceManager.getService(Context.BACKUP_SERVICE));
17041                 bm.agentDisconnected(app.info.packageName);
17042             } catch (RemoteException e) {
17043                 // can't happen; backup manager is local
17044             }
17045         }
17046
17047         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17048             ProcessChangeItem item = mPendingProcessChanges.get(i);
17049             if (item.pid == app.pid) {
17050                 mPendingProcessChanges.remove(i);
17051                 mAvailProcessChanges.add(item);
17052             }
17053         }
17054         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17055                 null).sendToTarget();
17056
17057         // If the caller is restarting this app, then leave it in its
17058         // current lists and let the caller take care of it.
17059         if (restarting) {
17060             return false;
17061         }
17062
17063         if (!app.persistent || app.isolated) {
17064             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17065                     "Removing non-persistent process during cleanup: " + app);
17066             if (!replacingPid) {
17067                 removeProcessNameLocked(app.processName, app.uid, app);
17068             }
17069             if (mHeavyWeightProcess == app) {
17070                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17071                         mHeavyWeightProcess.userId, 0));
17072                 mHeavyWeightProcess = null;
17073             }
17074         } else if (!app.removed) {
17075             // This app is persistent, so we need to keep its record around.
17076             // If it is not already on the pending app list, add it there
17077             // and start a new process for it.
17078             if (mPersistentStartingProcesses.indexOf(app) < 0) {
17079                 mPersistentStartingProcesses.add(app);
17080                 restart = true;
17081             }
17082         }
17083         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17084                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17085         mProcessesOnHold.remove(app);
17086
17087         if (app == mHomeProcess) {
17088             mHomeProcess = null;
17089         }
17090         if (app == mPreviousProcess) {
17091             mPreviousProcess = null;
17092         }
17093
17094         if (restart && !app.isolated) {
17095             // We have components that still need to be running in the
17096             // process, so re-launch it.
17097             if (index < 0) {
17098                 ProcessList.remove(app.pid);
17099             }
17100             addProcessNameLocked(app);
17101             startProcessLocked(app, "restart", app.processName);
17102             return true;
17103         } else if (app.pid > 0 && app.pid != MY_PID) {
17104             // Goodbye!
17105             boolean removed;
17106             synchronized (mPidsSelfLocked) {
17107                 mPidsSelfLocked.remove(app.pid);
17108                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17109             }
17110             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17111             if (app.isolated) {
17112                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17113             }
17114             app.setPid(0);
17115         }
17116         return false;
17117     }
17118
17119     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17120         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17121             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17122             if (cpr.launchingApp == app) {
17123                 return true;
17124             }
17125         }
17126         return false;
17127     }
17128
17129     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17130         // Look through the content providers we are waiting to have launched,
17131         // and if any run in this process then either schedule a restart of
17132         // the process or kill the client waiting for it if this process has
17133         // gone bad.
17134         boolean restart = false;
17135         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17136             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17137             if (cpr.launchingApp == app) {
17138                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17139                     restart = true;
17140                 } else {
17141                     removeDyingProviderLocked(app, cpr, true);
17142                 }
17143             }
17144         }
17145         return restart;
17146     }
17147
17148     // =========================================================
17149     // SERVICES
17150     // =========================================================
17151
17152     @Override
17153     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17154             int flags) {
17155         enforceNotIsolatedCaller("getServices");
17156         synchronized (this) {
17157             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17158         }
17159     }
17160
17161     @Override
17162     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17163         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17164         synchronized (this) {
17165             return mServices.getRunningServiceControlPanelLocked(name);
17166         }
17167     }
17168
17169     @Override
17170     public ComponentName startService(IApplicationThread caller, Intent service,
17171             String resolvedType, String callingPackage, int userId)
17172             throws TransactionTooLargeException {
17173         enforceNotIsolatedCaller("startService");
17174         // Refuse possible leaked file descriptors
17175         if (service != null && service.hasFileDescriptors() == true) {
17176             throw new IllegalArgumentException("File descriptors passed in Intent");
17177         }
17178
17179         if (callingPackage == null) {
17180             throw new IllegalArgumentException("callingPackage cannot be null");
17181         }
17182
17183         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17184                 "startService: " + service + " type=" + resolvedType);
17185         synchronized(this) {
17186             final int callingPid = Binder.getCallingPid();
17187             final int callingUid = Binder.getCallingUid();
17188             final long origId = Binder.clearCallingIdentity();
17189             ComponentName res = mServices.startServiceLocked(caller, service,
17190                     resolvedType, callingPid, callingUid, callingPackage, userId);
17191             Binder.restoreCallingIdentity(origId);
17192             return res;
17193         }
17194     }
17195
17196     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17197             String callingPackage, int userId)
17198             throws TransactionTooLargeException {
17199         synchronized(this) {
17200             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17201                     "startServiceInPackage: " + service + " type=" + resolvedType);
17202             final long origId = Binder.clearCallingIdentity();
17203             ComponentName res = mServices.startServiceLocked(null, service,
17204                     resolvedType, -1, uid, callingPackage, userId);
17205             Binder.restoreCallingIdentity(origId);
17206             return res;
17207         }
17208     }
17209
17210     @Override
17211     public int stopService(IApplicationThread caller, Intent service,
17212             String resolvedType, int userId) {
17213         enforceNotIsolatedCaller("stopService");
17214         // Refuse possible leaked file descriptors
17215         if (service != null && service.hasFileDescriptors() == true) {
17216             throw new IllegalArgumentException("File descriptors passed in Intent");
17217         }
17218
17219         synchronized(this) {
17220             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17221         }
17222     }
17223
17224     @Override
17225     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17226         enforceNotIsolatedCaller("peekService");
17227         // Refuse possible leaked file descriptors
17228         if (service != null && service.hasFileDescriptors() == true) {
17229             throw new IllegalArgumentException("File descriptors passed in Intent");
17230         }
17231
17232         if (callingPackage == null) {
17233             throw new IllegalArgumentException("callingPackage cannot be null");
17234         }
17235
17236         synchronized(this) {
17237             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17238         }
17239     }
17240
17241     @Override
17242     public boolean stopServiceToken(ComponentName className, IBinder token,
17243             int startId) {
17244         synchronized(this) {
17245             return mServices.stopServiceTokenLocked(className, token, startId);
17246         }
17247     }
17248
17249     @Override
17250     public void setServiceForeground(ComponentName className, IBinder token,
17251             int id, Notification notification, int flags) {
17252         synchronized(this) {
17253             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17254         }
17255     }
17256
17257     @Override
17258     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17259             boolean requireFull, String name, String callerPackage) {
17260         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17261                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17262     }
17263
17264     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17265             String className, int flags) {
17266         boolean result = false;
17267         // For apps that don't have pre-defined UIDs, check for permission
17268         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17269             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17270                 if (ActivityManager.checkUidPermission(
17271                         INTERACT_ACROSS_USERS,
17272                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17273                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17274                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17275                             + " requests FLAG_SINGLE_USER, but app does not hold "
17276                             + INTERACT_ACROSS_USERS;
17277                     Slog.w(TAG, msg);
17278                     throw new SecurityException(msg);
17279                 }
17280                 // Permission passed
17281                 result = true;
17282             }
17283         } else if ("system".equals(componentProcessName)) {
17284             result = true;
17285         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17286             // Phone app and persistent apps are allowed to export singleuser providers.
17287             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17288                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17289         }
17290         if (DEBUG_MU) Slog.v(TAG_MU,
17291                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17292                 + Integer.toHexString(flags) + ") = " + result);
17293         return result;
17294     }
17295
17296     /**
17297      * Checks to see if the caller is in the same app as the singleton
17298      * component, or the component is in a special app. It allows special apps
17299      * to export singleton components but prevents exporting singleton
17300      * components for regular apps.
17301      */
17302     boolean isValidSingletonCall(int callingUid, int componentUid) {
17303         int componentAppId = UserHandle.getAppId(componentUid);
17304         return UserHandle.isSameApp(callingUid, componentUid)
17305                 || componentAppId == Process.SYSTEM_UID
17306                 || componentAppId == Process.PHONE_UID
17307                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17308                         == PackageManager.PERMISSION_GRANTED;
17309     }
17310
17311     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17312             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17313             int userId) throws TransactionTooLargeException {
17314         enforceNotIsolatedCaller("bindService");
17315
17316         // Refuse possible leaked file descriptors
17317         if (service != null && service.hasFileDescriptors() == true) {
17318             throw new IllegalArgumentException("File descriptors passed in Intent");
17319         }
17320
17321         if (callingPackage == null) {
17322             throw new IllegalArgumentException("callingPackage cannot be null");
17323         }
17324
17325         synchronized(this) {
17326             return mServices.bindServiceLocked(caller, token, service,
17327                     resolvedType, connection, flags, callingPackage, userId);
17328         }
17329     }
17330
17331     public boolean unbindService(IServiceConnection connection) {
17332         synchronized (this) {
17333             return mServices.unbindServiceLocked(connection);
17334         }
17335     }
17336
17337     public void publishService(IBinder token, Intent intent, IBinder service) {
17338         // Refuse possible leaked file descriptors
17339         if (intent != null && intent.hasFileDescriptors() == true) {
17340             throw new IllegalArgumentException("File descriptors passed in Intent");
17341         }
17342
17343         synchronized(this) {
17344             if (!(token instanceof ServiceRecord)) {
17345                 throw new IllegalArgumentException("Invalid service token");
17346             }
17347             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17348         }
17349     }
17350
17351     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17352         // Refuse possible leaked file descriptors
17353         if (intent != null && intent.hasFileDescriptors() == true) {
17354             throw new IllegalArgumentException("File descriptors passed in Intent");
17355         }
17356
17357         synchronized(this) {
17358             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17359         }
17360     }
17361
17362     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17363         synchronized(this) {
17364             if (!(token instanceof ServiceRecord)) {
17365                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17366                 throw new IllegalArgumentException("Invalid service token");
17367             }
17368             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17369         }
17370     }
17371
17372     // =========================================================
17373     // BACKUP AND RESTORE
17374     // =========================================================
17375
17376     // Cause the target app to be launched if necessary and its backup agent
17377     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17378     // activity manager to announce its creation.
17379     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17380         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17381         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17382
17383         IPackageManager pm = AppGlobals.getPackageManager();
17384         ApplicationInfo app = null;
17385         try {
17386             app = pm.getApplicationInfo(packageName, 0, userId);
17387         } catch (RemoteException e) {
17388             // can't happen; package manager is process-local
17389         }
17390         if (app == null) {
17391             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17392             return false;
17393         }
17394
17395         synchronized(this) {
17396             // !!! TODO: currently no check here that we're already bound
17397             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17398             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17399             synchronized (stats) {
17400                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17401             }
17402
17403             // Backup agent is now in use, its package can't be stopped.
17404             try {
17405                 AppGlobals.getPackageManager().setPackageStoppedState(
17406                         app.packageName, false, UserHandle.getUserId(app.uid));
17407             } catch (RemoteException e) {
17408             } catch (IllegalArgumentException e) {
17409                 Slog.w(TAG, "Failed trying to unstop package "
17410                         + app.packageName + ": " + e);
17411             }
17412
17413             BackupRecord r = new BackupRecord(ss, app, backupMode);
17414             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17415                     ? new ComponentName(app.packageName, app.backupAgentName)
17416                     : new ComponentName("android", "FullBackupAgent");
17417             // startProcessLocked() returns existing proc's record if it's already running
17418             ProcessRecord proc = startProcessLocked(app.processName, app,
17419                     false, 0, "backup", hostingName, false, false, false);
17420             if (proc == null) {
17421                 Slog.e(TAG, "Unable to start backup agent process " + r);
17422                 return false;
17423             }
17424
17425             // If the app is a regular app (uid >= 10000) and not the system server or phone
17426             // process, etc, then mark it as being in full backup so that certain calls to the
17427             // process can be blocked. This is not reset to false anywhere because we kill the
17428             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17429             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17430                 proc.inFullBackup = true;
17431             }
17432             r.app = proc;
17433             mBackupTarget = r;
17434             mBackupAppName = app.packageName;
17435
17436             // Try not to kill the process during backup
17437             updateOomAdjLocked(proc);
17438
17439             // If the process is already attached, schedule the creation of the backup agent now.
17440             // If it is not yet live, this will be done when it attaches to the framework.
17441             if (proc.thread != null) {
17442                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17443                 try {
17444                     proc.thread.scheduleCreateBackupAgent(app,
17445                             compatibilityInfoForPackageLocked(app), backupMode);
17446                 } catch (RemoteException e) {
17447                     // Will time out on the backup manager side
17448                 }
17449             } else {
17450                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17451             }
17452             // Invariants: at this point, the target app process exists and the application
17453             // is either already running or in the process of coming up.  mBackupTarget and
17454             // mBackupAppName describe the app, so that when it binds back to the AM we
17455             // know that it's scheduled for a backup-agent operation.
17456         }
17457
17458         return true;
17459     }
17460
17461     @Override
17462     public void clearPendingBackup() {
17463         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17464         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17465
17466         synchronized (this) {
17467             mBackupTarget = null;
17468             mBackupAppName = null;
17469         }
17470     }
17471
17472     // A backup agent has just come up
17473     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17474         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17475                 + " = " + agent);
17476
17477         synchronized(this) {
17478             if (!agentPackageName.equals(mBackupAppName)) {
17479                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17480                 return;
17481             }
17482         }
17483
17484         long oldIdent = Binder.clearCallingIdentity();
17485         try {
17486             IBackupManager bm = IBackupManager.Stub.asInterface(
17487                     ServiceManager.getService(Context.BACKUP_SERVICE));
17488             bm.agentConnected(agentPackageName, agent);
17489         } catch (RemoteException e) {
17490             // can't happen; the backup manager service is local
17491         } catch (Exception e) {
17492             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17493             e.printStackTrace();
17494         } finally {
17495             Binder.restoreCallingIdentity(oldIdent);
17496         }
17497     }
17498
17499     // done with this agent
17500     public void unbindBackupAgent(ApplicationInfo appInfo) {
17501         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17502         if (appInfo == null) {
17503             Slog.w(TAG, "unbind backup agent for null app");
17504             return;
17505         }
17506
17507         synchronized(this) {
17508             try {
17509                 if (mBackupAppName == null) {
17510                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17511                     return;
17512                 }
17513
17514                 if (!mBackupAppName.equals(appInfo.packageName)) {
17515                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17516                     return;
17517                 }
17518
17519                 // Not backing this app up any more; reset its OOM adjustment
17520                 final ProcessRecord proc = mBackupTarget.app;
17521                 updateOomAdjLocked(proc);
17522
17523                 // If the app crashed during backup, 'thread' will be null here
17524                 if (proc.thread != null) {
17525                     try {
17526                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17527                                 compatibilityInfoForPackageLocked(appInfo));
17528                     } catch (Exception e) {
17529                         Slog.e(TAG, "Exception when unbinding backup agent:");
17530                         e.printStackTrace();
17531                     }
17532                 }
17533             } finally {
17534                 mBackupTarget = null;
17535                 mBackupAppName = null;
17536             }
17537         }
17538     }
17539     // =========================================================
17540     // BROADCASTS
17541     // =========================================================
17542
17543     boolean isPendingBroadcastProcessLocked(int pid) {
17544         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17545                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17546     }
17547
17548     void skipPendingBroadcastLocked(int pid) {
17549             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17550             for (BroadcastQueue queue : mBroadcastQueues) {
17551                 queue.skipPendingBroadcastLocked(pid);
17552             }
17553     }
17554
17555     // The app just attached; send any pending broadcasts that it should receive
17556     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17557         boolean didSomething = false;
17558         for (BroadcastQueue queue : mBroadcastQueues) {
17559             didSomething |= queue.sendPendingBroadcastsLocked(app);
17560         }
17561         return didSomething;
17562     }
17563
17564     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17565             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17566         enforceNotIsolatedCaller("registerReceiver");
17567         ArrayList<Intent> stickyIntents = null;
17568         ProcessRecord callerApp = null;
17569         int callingUid;
17570         int callingPid;
17571         synchronized(this) {
17572             if (caller != null) {
17573                 callerApp = getRecordForAppLocked(caller);
17574                 if (callerApp == null) {
17575                     throw new SecurityException(
17576                             "Unable to find app for caller " + caller
17577                             + " (pid=" + Binder.getCallingPid()
17578                             + ") when registering receiver " + receiver);
17579                 }
17580                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17581                         !callerApp.pkgList.containsKey(callerPackage) &&
17582                         !"android".equals(callerPackage)) {
17583                     throw new SecurityException("Given caller package " + callerPackage
17584                             + " is not running in process " + callerApp);
17585                 }
17586                 callingUid = callerApp.info.uid;
17587                 callingPid = callerApp.pid;
17588             } else {
17589                 callerPackage = null;
17590                 callingUid = Binder.getCallingUid();
17591                 callingPid = Binder.getCallingPid();
17592             }
17593
17594             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17595                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17596
17597             Iterator<String> actions = filter.actionsIterator();
17598             if (actions == null) {
17599                 ArrayList<String> noAction = new ArrayList<String>(1);
17600                 noAction.add(null);
17601                 actions = noAction.iterator();
17602             }
17603
17604             // Collect stickies of users
17605             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17606             while (actions.hasNext()) {
17607                 String action = actions.next();
17608                 for (int id : userIds) {
17609                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17610                     if (stickies != null) {
17611                         ArrayList<Intent> intents = stickies.get(action);
17612                         if (intents != null) {
17613                             if (stickyIntents == null) {
17614                                 stickyIntents = new ArrayList<Intent>();
17615                             }
17616                             stickyIntents.addAll(intents);
17617                         }
17618                     }
17619                 }
17620             }
17621         }
17622
17623         ArrayList<Intent> allSticky = null;
17624         if (stickyIntents != null) {
17625             final ContentResolver resolver = mContext.getContentResolver();
17626             // Look for any matching sticky broadcasts...
17627             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17628                 Intent intent = stickyIntents.get(i);
17629                 // If intent has scheme "content", it will need to acccess
17630                 // provider that needs to lock mProviderMap in ActivityThread
17631                 // and also it may need to wait application response, so we
17632                 // cannot lock ActivityManagerService here.
17633                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17634                     if (allSticky == null) {
17635                         allSticky = new ArrayList<Intent>();
17636                     }
17637                     allSticky.add(intent);
17638                 }
17639             }
17640         }
17641
17642         // The first sticky in the list is returned directly back to the client.
17643         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17644         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17645         if (receiver == null) {
17646             return sticky;
17647         }
17648
17649         synchronized (this) {
17650             if (callerApp != null && (callerApp.thread == null
17651                     || callerApp.thread.asBinder() != caller.asBinder())) {
17652                 // Original caller already died
17653                 return null;
17654             }
17655             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17656             if (rl == null) {
17657                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17658                         userId, receiver);
17659                 if (rl.app != null) {
17660                     rl.app.receivers.add(rl);
17661                 } else {
17662                     try {
17663                         receiver.asBinder().linkToDeath(rl, 0);
17664                     } catch (RemoteException e) {
17665                         return sticky;
17666                     }
17667                     rl.linkedToDeath = true;
17668                 }
17669                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17670             } else if (rl.uid != callingUid) {
17671                 throw new IllegalArgumentException(
17672                         "Receiver requested to register for uid " + callingUid
17673                         + " was previously registered for uid " + rl.uid);
17674             } else if (rl.pid != callingPid) {
17675                 throw new IllegalArgumentException(
17676                         "Receiver requested to register for pid " + callingPid
17677                         + " was previously registered for pid " + rl.pid);
17678             } else if (rl.userId != userId) {
17679                 throw new IllegalArgumentException(
17680                         "Receiver requested to register for user " + userId
17681                         + " was previously registered for user " + rl.userId);
17682             }
17683             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17684                     permission, callingUid, userId);
17685             rl.add(bf);
17686             if (!bf.debugCheck()) {
17687                 Slog.w(TAG, "==> For Dynamic broadcast");
17688             }
17689             mReceiverResolver.addFilter(bf);
17690
17691             // Enqueue broadcasts for all existing stickies that match
17692             // this filter.
17693             if (allSticky != null) {
17694                 ArrayList receivers = new ArrayList();
17695                 receivers.add(bf);
17696
17697                 final int stickyCount = allSticky.size();
17698                 for (int i = 0; i < stickyCount; i++) {
17699                     Intent intent = allSticky.get(i);
17700                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17701                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17702                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17703                             null, 0, null, null, false, true, true, -1);
17704                     queue.enqueueParallelBroadcastLocked(r);
17705                     queue.scheduleBroadcastsLocked();
17706                 }
17707             }
17708
17709             return sticky;
17710         }
17711     }
17712
17713     public void unregisterReceiver(IIntentReceiver receiver) {
17714         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17715
17716         final long origId = Binder.clearCallingIdentity();
17717         try {
17718             boolean doTrim = false;
17719
17720             synchronized(this) {
17721                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17722                 if (rl != null) {
17723                     final BroadcastRecord r = rl.curBroadcast;
17724                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17725                         final boolean doNext = r.queue.finishReceiverLocked(
17726                                 r, r.resultCode, r.resultData, r.resultExtras,
17727                                 r.resultAbort, false);
17728                         if (doNext) {
17729                             doTrim = true;
17730                             r.queue.processNextBroadcast(false);
17731                         }
17732                     }
17733
17734                     if (rl.app != null) {
17735                         rl.app.receivers.remove(rl);
17736                     }
17737                     removeReceiverLocked(rl);
17738                     if (rl.linkedToDeath) {
17739                         rl.linkedToDeath = false;
17740                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17741                     }
17742                 }
17743             }
17744
17745             // If we actually concluded any broadcasts, we might now be able
17746             // to trim the recipients' apps from our working set
17747             if (doTrim) {
17748                 trimApplications();
17749                 return;
17750             }
17751
17752         } finally {
17753             Binder.restoreCallingIdentity(origId);
17754         }
17755     }
17756
17757     void removeReceiverLocked(ReceiverList rl) {
17758         mRegisteredReceivers.remove(rl.receiver.asBinder());
17759         for (int i = rl.size() - 1; i >= 0; i--) {
17760             mReceiverResolver.removeFilter(rl.get(i));
17761         }
17762     }
17763
17764     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17765         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17766             ProcessRecord r = mLruProcesses.get(i);
17767             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17768                 try {
17769                     r.thread.dispatchPackageBroadcast(cmd, packages);
17770                 } catch (RemoteException ex) {
17771                 }
17772             }
17773         }
17774     }
17775
17776     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17777             int callingUid, int[] users) {
17778         // TODO: come back and remove this assumption to triage all broadcasts
17779         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17780
17781         List<ResolveInfo> receivers = null;
17782         try {
17783             HashSet<ComponentName> singleUserReceivers = null;
17784             boolean scannedFirstReceivers = false;
17785             for (int user : users) {
17786                 // Skip users that have Shell restrictions, with exception of always permitted
17787                 // Shell broadcasts
17788                 if (callingUid == Process.SHELL_UID
17789                         && mUserController.hasUserRestriction(
17790                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17791                         && !isPermittedShellBroadcast(intent)) {
17792                     continue;
17793                 }
17794                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17795                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17796                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17797                     // If this is not the system user, we need to check for
17798                     // any receivers that should be filtered out.
17799                     for (int i=0; i<newReceivers.size(); i++) {
17800                         ResolveInfo ri = newReceivers.get(i);
17801                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17802                             newReceivers.remove(i);
17803                             i--;
17804                         }
17805                     }
17806                 }
17807                 if (newReceivers != null && newReceivers.size() == 0) {
17808                     newReceivers = null;
17809                 }
17810                 if (receivers == null) {
17811                     receivers = newReceivers;
17812                 } else if (newReceivers != null) {
17813                     // We need to concatenate the additional receivers
17814                     // found with what we have do far.  This would be easy,
17815                     // but we also need to de-dup any receivers that are
17816                     // singleUser.
17817                     if (!scannedFirstReceivers) {
17818                         // Collect any single user receivers we had already retrieved.
17819                         scannedFirstReceivers = true;
17820                         for (int i=0; i<receivers.size(); i++) {
17821                             ResolveInfo ri = receivers.get(i);
17822                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17823                                 ComponentName cn = new ComponentName(
17824                                         ri.activityInfo.packageName, ri.activityInfo.name);
17825                                 if (singleUserReceivers == null) {
17826                                     singleUserReceivers = new HashSet<ComponentName>();
17827                                 }
17828                                 singleUserReceivers.add(cn);
17829                             }
17830                         }
17831                     }
17832                     // Add the new results to the existing results, tracking
17833                     // and de-dupping single user receivers.
17834                     for (int i=0; i<newReceivers.size(); i++) {
17835                         ResolveInfo ri = newReceivers.get(i);
17836                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17837                             ComponentName cn = new ComponentName(
17838                                     ri.activityInfo.packageName, ri.activityInfo.name);
17839                             if (singleUserReceivers == null) {
17840                                 singleUserReceivers = new HashSet<ComponentName>();
17841                             }
17842                             if (!singleUserReceivers.contains(cn)) {
17843                                 singleUserReceivers.add(cn);
17844                                 receivers.add(ri);
17845                             }
17846                         } else {
17847                             receivers.add(ri);
17848                         }
17849                     }
17850                 }
17851             }
17852         } catch (RemoteException ex) {
17853             // pm is in same process, this will never happen.
17854         }
17855         return receivers;
17856     }
17857
17858     private boolean isPermittedShellBroadcast(Intent intent) {
17859         // remote bugreport should always be allowed to be taken
17860         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17861     }
17862
17863     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17864             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17865         final String action = intent.getAction();
17866         if (isProtectedBroadcast
17867                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17868                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17869                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17870                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17871                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17872                 || Intent.ACTION_MASTER_CLEAR.equals(action)
17873                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17874                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17875                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17876                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17877                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17878             // Broadcast is either protected, or it's a public action that
17879             // we've relaxed, so it's fine for system internals to send.
17880             return;
17881         }
17882
17883         // This broadcast may be a problem...  but there are often system components that
17884         // want to send an internal broadcast to themselves, which is annoying to have to
17885         // explicitly list each action as a protected broadcast, so we will check for that
17886         // one safe case and allow it: an explicit broadcast, only being received by something
17887         // that has protected itself.
17888         if (receivers != null && receivers.size() > 0
17889                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17890             boolean allProtected = true;
17891             for (int i = receivers.size()-1; i >= 0; i--) {
17892                 Object target = receivers.get(i);
17893                 if (target instanceof ResolveInfo) {
17894                     ResolveInfo ri = (ResolveInfo)target;
17895                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17896                         allProtected = false;
17897                         break;
17898                     }
17899                 } else {
17900                     BroadcastFilter bf = (BroadcastFilter)target;
17901                     if (bf.requiredPermission == null) {
17902                         allProtected = false;
17903                         break;
17904                     }
17905                 }
17906             }
17907             if (allProtected) {
17908                 // All safe!
17909                 return;
17910             }
17911         }
17912
17913         // The vast majority of broadcasts sent from system internals
17914         // should be protected to avoid security holes, so yell loudly
17915         // to ensure we examine these cases.
17916         if (callerApp != null) {
17917             Log.wtf(TAG, "Sending non-protected broadcast " + action
17918                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17919                     new Throwable());
17920         } else {
17921             Log.wtf(TAG, "Sending non-protected broadcast " + action
17922                             + " from system uid " + UserHandle.formatUid(callingUid)
17923                             + " pkg " + callerPackage,
17924                     new Throwable());
17925         }
17926     }
17927
17928     final int broadcastIntentLocked(ProcessRecord callerApp,
17929             String callerPackage, Intent intent, String resolvedType,
17930             IIntentReceiver resultTo, int resultCode, String resultData,
17931             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17932             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17933         intent = new Intent(intent);
17934
17935         // By default broadcasts do not go to stopped apps.
17936         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17937
17938         // If we have not finished booting, don't allow this to launch new processes.
17939         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17940             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17941         }
17942
17943         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17944                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17945                 + " ordered=" + ordered + " userid=" + userId);
17946         if ((resultTo != null) && !ordered) {
17947             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17948         }
17949
17950         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17951                 ALLOW_NON_FULL, "broadcast", callerPackage);
17952
17953         // Make sure that the user who is receiving this broadcast is running.
17954         // If not, we will just skip it. Make an exception for shutdown broadcasts
17955         // and upgrade steps.
17956
17957         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17958             if ((callingUid != Process.SYSTEM_UID
17959                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17960                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17961                 Slog.w(TAG, "Skipping broadcast of " + intent
17962                         + ": user " + userId + " is stopped");
17963                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17964             }
17965         }
17966
17967         BroadcastOptions brOptions = null;
17968         if (bOptions != null) {
17969             brOptions = new BroadcastOptions(bOptions);
17970             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17971                 // See if the caller is allowed to do this.  Note we are checking against
17972                 // the actual real caller (not whoever provided the operation as say a
17973                 // PendingIntent), because that who is actually supplied the arguments.
17974                 if (checkComponentPermission(
17975                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17976                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17977                         != PackageManager.PERMISSION_GRANTED) {
17978                     String msg = "Permission Denial: " + intent.getAction()
17979                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17980                             + ", uid=" + callingUid + ")"
17981                             + " requires "
17982                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17983                     Slog.w(TAG, msg);
17984                     throw new SecurityException(msg);
17985                 }
17986             }
17987         }
17988
17989         // Verify that protected broadcasts are only being sent by system code,
17990         // and that system code is only sending protected broadcasts.
17991         final String action = intent.getAction();
17992         final boolean isProtectedBroadcast;
17993         try {
17994             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17995         } catch (RemoteException e) {
17996             Slog.w(TAG, "Remote exception", e);
17997             return ActivityManager.BROADCAST_SUCCESS;
17998         }
17999
18000         final boolean isCallerSystem;
18001         switch (UserHandle.getAppId(callingUid)) {
18002             case Process.ROOT_UID:
18003             case Process.SYSTEM_UID:
18004             case Process.PHONE_UID:
18005             case Process.BLUETOOTH_UID:
18006             case Process.NFC_UID:
18007                 isCallerSystem = true;
18008                 break;
18009             default:
18010                 isCallerSystem = (callerApp != null) && callerApp.persistent;
18011                 break;
18012         }
18013
18014         // First line security check before anything else: stop non-system apps from
18015         // sending protected broadcasts.
18016         if (!isCallerSystem) {
18017             if (isProtectedBroadcast) {
18018                 String msg = "Permission Denial: not allowed to send broadcast "
18019                         + action + " from pid="
18020                         + callingPid + ", uid=" + callingUid;
18021                 Slog.w(TAG, msg);
18022                 throw new SecurityException(msg);
18023
18024             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18025                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18026                 // Special case for compatibility: we don't want apps to send this,
18027                 // but historically it has not been protected and apps may be using it
18028                 // to poke their own app widget.  So, instead of making it protected,
18029                 // just limit it to the caller.
18030                 if (callerPackage == null) {
18031                     String msg = "Permission Denial: not allowed to send broadcast "
18032                             + action + " from unknown caller.";
18033                     Slog.w(TAG, msg);
18034                     throw new SecurityException(msg);
18035                 } else if (intent.getComponent() != null) {
18036                     // They are good enough to send to an explicit component...  verify
18037                     // it is being sent to the calling app.
18038                     if (!intent.getComponent().getPackageName().equals(
18039                             callerPackage)) {
18040                         String msg = "Permission Denial: not allowed to send broadcast "
18041                                 + action + " to "
18042                                 + intent.getComponent().getPackageName() + " from "
18043                                 + callerPackage;
18044                         Slog.w(TAG, msg);
18045                         throw new SecurityException(msg);
18046                     }
18047                 } else {
18048                     // Limit broadcast to their own package.
18049                     intent.setPackage(callerPackage);
18050                 }
18051             }
18052         }
18053
18054         if (action != null) {
18055             switch (action) {
18056                 case Intent.ACTION_UID_REMOVED:
18057                 case Intent.ACTION_PACKAGE_REMOVED:
18058                 case Intent.ACTION_PACKAGE_CHANGED:
18059                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18060                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18061                 case Intent.ACTION_PACKAGES_SUSPENDED:
18062                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18063                     // Handle special intents: if this broadcast is from the package
18064                     // manager about a package being removed, we need to remove all of
18065                     // its activities from the history stack.
18066                     if (checkComponentPermission(
18067                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18068                             callingPid, callingUid, -1, true)
18069                             != PackageManager.PERMISSION_GRANTED) {
18070                         String msg = "Permission Denial: " + intent.getAction()
18071                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
18072                                 + ", uid=" + callingUid + ")"
18073                                 + " requires "
18074                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18075                         Slog.w(TAG, msg);
18076                         throw new SecurityException(msg);
18077                     }
18078                     switch (action) {
18079                         case Intent.ACTION_UID_REMOVED:
18080                             final Bundle intentExtras = intent.getExtras();
18081                             final int uid = intentExtras != null
18082                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18083                             if (uid >= 0) {
18084                                 mBatteryStatsService.removeUid(uid);
18085                                 mAppOpsService.uidRemoved(uid);
18086                             }
18087                             break;
18088                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18089                             // If resources are unavailable just force stop all those packages
18090                             // and flush the attribute cache as well.
18091                             String list[] =
18092                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18093                             if (list != null && list.length > 0) {
18094                                 for (int i = 0; i < list.length; i++) {
18095                                     forceStopPackageLocked(list[i], -1, false, true, true,
18096                                             false, false, userId, "storage unmount");
18097                                 }
18098                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18099                                 sendPackageBroadcastLocked(
18100                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18101                                         userId);
18102                             }
18103                             break;
18104                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18105                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18106                             break;
18107                         case Intent.ACTION_PACKAGE_REMOVED:
18108                         case Intent.ACTION_PACKAGE_CHANGED:
18109                             Uri data = intent.getData();
18110                             String ssp;
18111                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18112                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18113                                 final boolean replacing =
18114                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18115                                 final boolean killProcess =
18116                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18117                                 final boolean fullUninstall = removed && !replacing;
18118                                 if (removed) {
18119                                     if (killProcess) {
18120                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18121                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18122                                                 false, true, true, false, fullUninstall, userId,
18123                                                 removed ? "pkg removed" : "pkg changed");
18124                                     }
18125                                     final int cmd = killProcess
18126                                             ? IApplicationThread.PACKAGE_REMOVED
18127                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18128                                     sendPackageBroadcastLocked(cmd,
18129                                             new String[] {ssp}, userId);
18130                                     if (fullUninstall) {
18131                                         mAppOpsService.packageRemoved(
18132                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18133
18134                                         // Remove all permissions granted from/to this package
18135                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18136
18137                                         removeTasksByPackageNameLocked(ssp, userId);
18138
18139                                         // Hide the "unsupported display" dialog if necessary.
18140                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18141                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18142                                             mUnsupportedDisplaySizeDialog.dismiss();
18143                                             mUnsupportedDisplaySizeDialog = null;
18144                                         }
18145                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18146                                         mBatteryStatsService.notePackageUninstalled(ssp);
18147                                     }
18148                                 } else {
18149                                     if (killProcess) {
18150                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18151                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18152                                                 userId, ProcessList.INVALID_ADJ,
18153                                                 false, true, true, false, "change " + ssp);
18154                                     }
18155                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18156                                             intent.getStringArrayExtra(
18157                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18158                                 }
18159                             }
18160                             break;
18161                         case Intent.ACTION_PACKAGES_SUSPENDED:
18162                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18163                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18164                                     intent.getAction());
18165                             final String[] packageNames = intent.getStringArrayExtra(
18166                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18167                             final int userHandle = intent.getIntExtra(
18168                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18169
18170                             synchronized(ActivityManagerService.this) {
18171                                 mRecentTasks.onPackagesSuspendedChanged(
18172                                         packageNames, suspended, userHandle);
18173                             }
18174                             break;
18175                     }
18176                     break;
18177                 case Intent.ACTION_PACKAGE_REPLACED:
18178                 {
18179                     final Uri data = intent.getData();
18180                     final String ssp;
18181                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18182                         final ApplicationInfo aInfo =
18183                                 getPackageManagerInternalLocked().getApplicationInfo(
18184                                         ssp,
18185                                         userId);
18186                         if (aInfo == null) {
18187                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18188                                     + " ssp=" + ssp + " data=" + data);
18189                             return ActivityManager.BROADCAST_SUCCESS;
18190                         }
18191                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18192                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18193                                 new String[] {ssp}, userId);
18194                     }
18195                     break;
18196                 }
18197                 case Intent.ACTION_PACKAGE_ADDED:
18198                 {
18199                     // Special case for adding a package: by default turn on compatibility mode.
18200                     Uri data = intent.getData();
18201                     String ssp;
18202                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18203                         final boolean replacing =
18204                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18205                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18206
18207                         try {
18208                             ApplicationInfo ai = AppGlobals.getPackageManager().
18209                                     getApplicationInfo(ssp, 0, 0);
18210                             mBatteryStatsService.notePackageInstalled(ssp,
18211                                     ai != null ? ai.versionCode : 0);
18212                         } catch (RemoteException e) {
18213                         }
18214                     }
18215                     break;
18216                 }
18217                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18218                 {
18219                     Uri data = intent.getData();
18220                     String ssp;
18221                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18222                         // Hide the "unsupported display" dialog if necessary.
18223                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18224                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18225                             mUnsupportedDisplaySizeDialog.dismiss();
18226                             mUnsupportedDisplaySizeDialog = null;
18227                         }
18228                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18229                     }
18230                     break;
18231                 }
18232                 case Intent.ACTION_TIMEZONE_CHANGED:
18233                     // If this is the time zone changed action, queue up a message that will reset
18234                     // the timezone of all currently running processes. This message will get
18235                     // queued up before the broadcast happens.
18236                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18237                     break;
18238                 case Intent.ACTION_TIME_CHANGED:
18239                     // If the user set the time, let all running processes know.
18240                     final int is24Hour =
18241                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18242                                     : 0;
18243                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18244                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18245                     synchronized (stats) {
18246                         stats.noteCurrentTimeChangedLocked();
18247                     }
18248                     break;
18249                 case Intent.ACTION_CLEAR_DNS_CACHE:
18250                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18251                     break;
18252                 case Proxy.PROXY_CHANGE_ACTION:
18253                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18254                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18255                     break;
18256                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18257                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18258                     // These broadcasts are no longer allowed by the system, since they can
18259                     // cause significant thrashing at a crictical point (using the camera).
18260                     // Apps should use JobScehduler to monitor for media provider changes.
18261                     Slog.w(TAG, action + " no longer allowed; dropping from "
18262                             + UserHandle.formatUid(callingUid));
18263                     if (resultTo != null) {
18264                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18265                         try {
18266                             queue.performReceiveLocked(callerApp, resultTo, intent,
18267                                     Activity.RESULT_CANCELED, null, null,
18268                                     false, false, userId);
18269                         } catch (RemoteException e) {
18270                             Slog.w(TAG, "Failure ["
18271                                     + queue.mQueueName + "] sending broadcast result of "
18272                                     + intent, e);
18273
18274                         }
18275                     }
18276                     // Lie; we don't want to crash the app.
18277                     return ActivityManager.BROADCAST_SUCCESS;
18278             }
18279         }
18280
18281         // Add to the sticky list if requested.
18282         if (sticky) {
18283             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18284                     callingPid, callingUid)
18285                     != PackageManager.PERMISSION_GRANTED) {
18286                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18287                         + callingPid + ", uid=" + callingUid
18288                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18289                 Slog.w(TAG, msg);
18290                 throw new SecurityException(msg);
18291             }
18292             if (requiredPermissions != null && requiredPermissions.length > 0) {
18293                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18294                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18295                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18296             }
18297             if (intent.getComponent() != null) {
18298                 throw new SecurityException(
18299                         "Sticky broadcasts can't target a specific component");
18300             }
18301             // We use userId directly here, since the "all" target is maintained
18302             // as a separate set of sticky broadcasts.
18303             if (userId != UserHandle.USER_ALL) {
18304                 // But first, if this is not a broadcast to all users, then
18305                 // make sure it doesn't conflict with an existing broadcast to
18306                 // all users.
18307                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18308                         UserHandle.USER_ALL);
18309                 if (stickies != null) {
18310                     ArrayList<Intent> list = stickies.get(intent.getAction());
18311                     if (list != null) {
18312                         int N = list.size();
18313                         int i;
18314                         for (i=0; i<N; i++) {
18315                             if (intent.filterEquals(list.get(i))) {
18316                                 throw new IllegalArgumentException(
18317                                         "Sticky broadcast " + intent + " for user "
18318                                         + userId + " conflicts with existing global broadcast");
18319                             }
18320                         }
18321                     }
18322                 }
18323             }
18324             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18325             if (stickies == null) {
18326                 stickies = new ArrayMap<>();
18327                 mStickyBroadcasts.put(userId, stickies);
18328             }
18329             ArrayList<Intent> list = stickies.get(intent.getAction());
18330             if (list == null) {
18331                 list = new ArrayList<>();
18332                 stickies.put(intent.getAction(), list);
18333             }
18334             final int stickiesCount = list.size();
18335             int i;
18336             for (i = 0; i < stickiesCount; i++) {
18337                 if (intent.filterEquals(list.get(i))) {
18338                     // This sticky already exists, replace it.
18339                     list.set(i, new Intent(intent));
18340                     break;
18341                 }
18342             }
18343             if (i >= stickiesCount) {
18344                 list.add(new Intent(intent));
18345             }
18346         }
18347
18348         int[] users;
18349         if (userId == UserHandle.USER_ALL) {
18350             // Caller wants broadcast to go to all started users.
18351             users = mUserController.getStartedUserArrayLocked();
18352         } else {
18353             // Caller wants broadcast to go to one specific user.
18354             users = new int[] {userId};
18355         }
18356
18357         // Figure out who all will receive this broadcast.
18358         List receivers = null;
18359         List<BroadcastFilter> registeredReceivers = null;
18360         // Need to resolve the intent to interested receivers...
18361         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18362                  == 0) {
18363             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18364         }
18365         if (intent.getComponent() == null) {
18366             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18367                 // Query one target user at a time, excluding shell-restricted users
18368                 for (int i = 0; i < users.length; i++) {
18369                     if (mUserController.hasUserRestriction(
18370                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18371                         continue;
18372                     }
18373                     List<BroadcastFilter> registeredReceiversForUser =
18374                             mReceiverResolver.queryIntent(intent,
18375                                     resolvedType, false, users[i]);
18376                     if (registeredReceivers == null) {
18377                         registeredReceivers = registeredReceiversForUser;
18378                     } else if (registeredReceiversForUser != null) {
18379                         registeredReceivers.addAll(registeredReceiversForUser);
18380                     }
18381                 }
18382             } else {
18383                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18384                         resolvedType, false, userId);
18385             }
18386         }
18387
18388         final boolean replacePending =
18389                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18390
18391         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18392                 + " replacePending=" + replacePending);
18393
18394         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18395         if (!ordered && NR > 0) {
18396             // If we are not serializing this broadcast, then send the
18397             // registered receivers separately so they don't wait for the
18398             // components to be launched.
18399             if (isCallerSystem) {
18400                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18401                         isProtectedBroadcast, registeredReceivers);
18402             }
18403             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18404             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18405                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18406                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18407                     resultExtras, ordered, sticky, false, userId);
18408             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18409             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18410             if (!replaced) {
18411                 queue.enqueueParallelBroadcastLocked(r);
18412                 queue.scheduleBroadcastsLocked();
18413             }
18414             registeredReceivers = null;
18415             NR = 0;
18416         }
18417
18418         // Merge into one list.
18419         int ir = 0;
18420         if (receivers != null) {
18421             // A special case for PACKAGE_ADDED: do not allow the package
18422             // being added to see this broadcast.  This prevents them from
18423             // using this as a back door to get run as soon as they are
18424             // installed.  Maybe in the future we want to have a special install
18425             // broadcast or such for apps, but we'd like to deliberately make
18426             // this decision.
18427             String skipPackages[] = null;
18428             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18429                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18430                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18431                 Uri data = intent.getData();
18432                 if (data != null) {
18433                     String pkgName = data.getSchemeSpecificPart();
18434                     if (pkgName != null) {
18435                         skipPackages = new String[] { pkgName };
18436                     }
18437                 }
18438             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18439                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18440             }
18441             if (skipPackages != null && (skipPackages.length > 0)) {
18442                 for (String skipPackage : skipPackages) {
18443                     if (skipPackage != null) {
18444                         int NT = receivers.size();
18445                         for (int it=0; it<NT; it++) {
18446                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18447                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18448                                 receivers.remove(it);
18449                                 it--;
18450                                 NT--;
18451                             }
18452                         }
18453                     }
18454                 }
18455             }
18456
18457             int NT = receivers != null ? receivers.size() : 0;
18458             int it = 0;
18459             ResolveInfo curt = null;
18460             BroadcastFilter curr = null;
18461             while (it < NT && ir < NR) {
18462                 if (curt == null) {
18463                     curt = (ResolveInfo)receivers.get(it);
18464                 }
18465                 if (curr == null) {
18466                     curr = registeredReceivers.get(ir);
18467                 }
18468                 if (curr.getPriority() >= curt.priority) {
18469                     // Insert this broadcast record into the final list.
18470                     receivers.add(it, curr);
18471                     ir++;
18472                     curr = null;
18473                     it++;
18474                     NT++;
18475                 } else {
18476                     // Skip to the next ResolveInfo in the final list.
18477                     it++;
18478                     curt = null;
18479                 }
18480             }
18481         }
18482         while (ir < NR) {
18483             if (receivers == null) {
18484                 receivers = new ArrayList();
18485             }
18486             receivers.add(registeredReceivers.get(ir));
18487             ir++;
18488         }
18489
18490         if (isCallerSystem) {
18491             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18492                     isProtectedBroadcast, receivers);
18493         }
18494
18495         if ((receivers != null && receivers.size() > 0)
18496                 || resultTo != null) {
18497             BroadcastQueue queue = broadcastQueueForIntent(intent);
18498             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18499                     callerPackage, callingPid, callingUid, resolvedType,
18500                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18501                     resultData, resultExtras, ordered, sticky, false, userId);
18502
18503             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18504                     + ": prev had " + queue.mOrderedBroadcasts.size());
18505             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18506                     "Enqueueing broadcast " + r.intent.getAction());
18507
18508             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18509             if (!replaced) {
18510                 queue.enqueueOrderedBroadcastLocked(r);
18511                 queue.scheduleBroadcastsLocked();
18512             }
18513         } else {
18514             // There was nobody interested in the broadcast, but we still want to record
18515             // that it happened.
18516             if (intent.getComponent() == null && intent.getPackage() == null
18517                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18518                 // This was an implicit broadcast... let's record it for posterity.
18519                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18520             }
18521         }
18522
18523         return ActivityManager.BROADCAST_SUCCESS;
18524     }
18525
18526     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18527             int skipCount, long dispatchTime) {
18528         final long now = SystemClock.elapsedRealtime();
18529         if (mCurBroadcastStats == null ||
18530                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18531             mLastBroadcastStats = mCurBroadcastStats;
18532             if (mLastBroadcastStats != null) {
18533                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18534                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18535             }
18536             mCurBroadcastStats = new BroadcastStats();
18537         }
18538         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18539     }
18540
18541     final Intent verifyBroadcastLocked(Intent intent) {
18542         // Refuse possible leaked file descriptors
18543         if (intent != null && intent.hasFileDescriptors() == true) {
18544             throw new IllegalArgumentException("File descriptors passed in Intent");
18545         }
18546
18547         int flags = intent.getFlags();
18548
18549         if (!mProcessesReady) {
18550             // if the caller really truly claims to know what they're doing, go
18551             // ahead and allow the broadcast without launching any receivers
18552             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18553                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18554             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18555                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18556                         + " before boot completion");
18557                 throw new IllegalStateException("Cannot broadcast before boot completed");
18558             }
18559         }
18560
18561         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18562             throw new IllegalArgumentException(
18563                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18564         }
18565
18566         return intent;
18567     }
18568
18569     public final int broadcastIntent(IApplicationThread caller,
18570             Intent intent, String resolvedType, IIntentReceiver resultTo,
18571             int resultCode, String resultData, Bundle resultExtras,
18572             String[] requiredPermissions, int appOp, Bundle bOptions,
18573             boolean serialized, boolean sticky, int userId) {
18574         enforceNotIsolatedCaller("broadcastIntent");
18575         synchronized(this) {
18576             intent = verifyBroadcastLocked(intent);
18577
18578             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18579             final int callingPid = Binder.getCallingPid();
18580             final int callingUid = Binder.getCallingUid();
18581             final long origId = Binder.clearCallingIdentity();
18582             int res = broadcastIntentLocked(callerApp,
18583                     callerApp != null ? callerApp.info.packageName : null,
18584                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18585                     requiredPermissions, appOp, bOptions, serialized, sticky,
18586                     callingPid, callingUid, userId);
18587             Binder.restoreCallingIdentity(origId);
18588             return res;
18589         }
18590     }
18591
18592
18593     int broadcastIntentInPackage(String packageName, int uid,
18594             Intent intent, String resolvedType, IIntentReceiver resultTo,
18595             int resultCode, String resultData, Bundle resultExtras,
18596             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18597             int userId) {
18598         synchronized(this) {
18599             intent = verifyBroadcastLocked(intent);
18600
18601             final long origId = Binder.clearCallingIdentity();
18602             String[] requiredPermissions = requiredPermission == null ? null
18603                     : new String[] {requiredPermission};
18604             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18605                     resultTo, resultCode, resultData, resultExtras,
18606                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18607                     sticky, -1, uid, userId);
18608             Binder.restoreCallingIdentity(origId);
18609             return res;
18610         }
18611     }
18612
18613     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18614         // Refuse possible leaked file descriptors
18615         if (intent != null && intent.hasFileDescriptors() == true) {
18616             throw new IllegalArgumentException("File descriptors passed in Intent");
18617         }
18618
18619         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18620                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18621
18622         synchronized(this) {
18623             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18624                     != PackageManager.PERMISSION_GRANTED) {
18625                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18626                         + Binder.getCallingPid()
18627                         + ", uid=" + Binder.getCallingUid()
18628                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18629                 Slog.w(TAG, msg);
18630                 throw new SecurityException(msg);
18631             }
18632             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18633             if (stickies != null) {
18634                 ArrayList<Intent> list = stickies.get(intent.getAction());
18635                 if (list != null) {
18636                     int N = list.size();
18637                     int i;
18638                     for (i=0; i<N; i++) {
18639                         if (intent.filterEquals(list.get(i))) {
18640                             list.remove(i);
18641                             break;
18642                         }
18643                     }
18644                     if (list.size() <= 0) {
18645                         stickies.remove(intent.getAction());
18646                     }
18647                 }
18648                 if (stickies.size() <= 0) {
18649                     mStickyBroadcasts.remove(userId);
18650                 }
18651             }
18652         }
18653     }
18654
18655     void backgroundServicesFinishedLocked(int userId) {
18656         for (BroadcastQueue queue : mBroadcastQueues) {
18657             queue.backgroundServicesFinishedLocked(userId);
18658         }
18659     }
18660
18661     public void finishReceiver(IBinder who, int resultCode, String resultData,
18662             Bundle resultExtras, boolean resultAbort, int flags) {
18663         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18664
18665         // Refuse possible leaked file descriptors
18666         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18667             throw new IllegalArgumentException("File descriptors passed in Bundle");
18668         }
18669
18670         final long origId = Binder.clearCallingIdentity();
18671         try {
18672             boolean doNext = false;
18673             BroadcastRecord r;
18674
18675             synchronized(this) {
18676                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18677                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18678                 r = queue.getMatchingOrderedReceiver(who);
18679                 if (r != null) {
18680                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18681                         resultData, resultExtras, resultAbort, true);
18682                 }
18683             }
18684
18685             if (doNext) {
18686                 r.queue.processNextBroadcast(false);
18687             }
18688             trimApplications();
18689         } finally {
18690             Binder.restoreCallingIdentity(origId);
18691         }
18692     }
18693
18694     // =========================================================
18695     // INSTRUMENTATION
18696     // =========================================================
18697
18698     public boolean startInstrumentation(ComponentName className,
18699             String profileFile, int flags, Bundle arguments,
18700             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18701             int userId, String abiOverride) {
18702         enforceNotIsolatedCaller("startInstrumentation");
18703         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18704                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18705         // Refuse possible leaked file descriptors
18706         if (arguments != null && arguments.hasFileDescriptors()) {
18707             throw new IllegalArgumentException("File descriptors passed in Bundle");
18708         }
18709
18710         synchronized(this) {
18711             InstrumentationInfo ii = null;
18712             ApplicationInfo ai = null;
18713             try {
18714                 ii = mContext.getPackageManager().getInstrumentationInfo(
18715                     className, STOCK_PM_FLAGS);
18716                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18717                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18718             } catch (PackageManager.NameNotFoundException e) {
18719             } catch (RemoteException e) {
18720             }
18721             if (ii == null) {
18722                 reportStartInstrumentationFailureLocked(watcher, className,
18723                         "Unable to find instrumentation info for: " + className);
18724                 return false;
18725             }
18726             if (ai == null) {
18727                 reportStartInstrumentationFailureLocked(watcher, className,
18728                         "Unable to find instrumentation target package: " + ii.targetPackage);
18729                 return false;
18730             }
18731             if (!ai.hasCode()) {
18732                 reportStartInstrumentationFailureLocked(watcher, className,
18733                         "Instrumentation target has no code: " + ii.targetPackage);
18734                 return false;
18735             }
18736
18737             int match = mContext.getPackageManager().checkSignatures(
18738                     ii.targetPackage, ii.packageName);
18739             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18740                 String msg = "Permission Denial: starting instrumentation "
18741                         + className + " from pid="
18742                         + Binder.getCallingPid()
18743                         + ", uid=" + Binder.getCallingPid()
18744                         + " not allowed because package " + ii.packageName
18745                         + " does not have a signature matching the target "
18746                         + ii.targetPackage;
18747                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18748                 throw new SecurityException(msg);
18749             }
18750
18751             final long origId = Binder.clearCallingIdentity();
18752             // Instrumentation can kill and relaunch even persistent processes
18753             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18754                     "start instr");
18755             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18756             app.instrumentationClass = className;
18757             app.instrumentationInfo = ai;
18758             app.instrumentationProfileFile = profileFile;
18759             app.instrumentationArguments = arguments;
18760             app.instrumentationWatcher = watcher;
18761             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18762             app.instrumentationResultClass = className;
18763             Binder.restoreCallingIdentity(origId);
18764         }
18765
18766         return true;
18767     }
18768
18769     /**
18770      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18771      * error to the logs, but if somebody is watching, send the report there too.  This enables
18772      * the "am" command to report errors with more information.
18773      *
18774      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18775      * @param cn The component name of the instrumentation.
18776      * @param report The error report.
18777      */
18778     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18779             ComponentName cn, String report) {
18780         Slog.w(TAG, report);
18781         if (watcher != null) {
18782             Bundle results = new Bundle();
18783             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18784             results.putString("Error", report);
18785             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18786         }
18787     }
18788
18789     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18790         if (app.instrumentationWatcher != null) {
18791             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18792                     app.instrumentationClass, resultCode, results);
18793         }
18794
18795         // Can't call out of the system process with a lock held, so post a message.
18796         if (app.instrumentationUiAutomationConnection != null) {
18797             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18798                     app.instrumentationUiAutomationConnection).sendToTarget();
18799         }
18800
18801         app.instrumentationWatcher = null;
18802         app.instrumentationUiAutomationConnection = null;
18803         app.instrumentationClass = null;
18804         app.instrumentationInfo = null;
18805         app.instrumentationProfileFile = null;
18806         app.instrumentationArguments = null;
18807
18808         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18809                 "finished inst");
18810     }
18811
18812     public void finishInstrumentation(IApplicationThread target,
18813             int resultCode, Bundle results) {
18814         int userId = UserHandle.getCallingUserId();
18815         // Refuse possible leaked file descriptors
18816         if (results != null && results.hasFileDescriptors()) {
18817             throw new IllegalArgumentException("File descriptors passed in Intent");
18818         }
18819
18820         synchronized(this) {
18821             ProcessRecord app = getRecordForAppLocked(target);
18822             if (app == null) {
18823                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18824                 return;
18825             }
18826             final long origId = Binder.clearCallingIdentity();
18827             finishInstrumentationLocked(app, resultCode, results);
18828             Binder.restoreCallingIdentity(origId);
18829         }
18830     }
18831
18832     // =========================================================
18833     // CONFIGURATION
18834     // =========================================================
18835
18836     public ConfigurationInfo getDeviceConfigurationInfo() {
18837         ConfigurationInfo config = new ConfigurationInfo();
18838         synchronized (this) {
18839             config.reqTouchScreen = mConfiguration.touchscreen;
18840             config.reqKeyboardType = mConfiguration.keyboard;
18841             config.reqNavigation = mConfiguration.navigation;
18842             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18843                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18844                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18845             }
18846             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18847                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18848                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18849             }
18850             config.reqGlEsVersion = GL_ES_VERSION;
18851         }
18852         return config;
18853     }
18854
18855     ActivityStack getFocusedStack() {
18856         return mStackSupervisor.getFocusedStack();
18857     }
18858
18859     @Override
18860     public int getFocusedStackId() throws RemoteException {
18861         ActivityStack focusedStack = getFocusedStack();
18862         if (focusedStack != null) {
18863             return focusedStack.getStackId();
18864         }
18865         return -1;
18866     }
18867
18868     public Configuration getConfiguration() {
18869         Configuration ci;
18870         synchronized(this) {
18871             ci = new Configuration(mConfiguration);
18872             ci.userSetLocale = false;
18873         }
18874         return ci;
18875     }
18876
18877     @Override
18878     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18879         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18880         synchronized (this) {
18881             mSuppressResizeConfigChanges = suppress;
18882         }
18883     }
18884
18885     @Override
18886     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18887         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18888         if (fromStackId == HOME_STACK_ID) {
18889             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18890         }
18891         synchronized (this) {
18892             final long origId = Binder.clearCallingIdentity();
18893             try {
18894                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18895             } finally {
18896                 Binder.restoreCallingIdentity(origId);
18897             }
18898         }
18899     }
18900
18901     @Override
18902     public void updatePersistentConfiguration(Configuration values) {
18903         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18904                 "updateConfiguration()");
18905         enforceWriteSettingsPermission("updateConfiguration()");
18906         if (values == null) {
18907             throw new NullPointerException("Configuration must not be null");
18908         }
18909
18910         int userId = UserHandle.getCallingUserId();
18911
18912         synchronized(this) {
18913             updatePersistentConfigurationLocked(values, userId);
18914         }
18915     }
18916
18917     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18918         final long origId = Binder.clearCallingIdentity();
18919         try {
18920             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18921         } finally {
18922             Binder.restoreCallingIdentity(origId);
18923         }
18924     }
18925
18926     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18927         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18928                 FONT_SCALE, 1.0f, userId);
18929         if (mConfiguration.fontScale != scaleFactor) {
18930             final Configuration configuration = mWindowManager.computeNewConfiguration();
18931             configuration.fontScale = scaleFactor;
18932             synchronized (this) {
18933                 updatePersistentConfigurationLocked(configuration, userId);
18934             }
18935         }
18936     }
18937
18938     private void enforceWriteSettingsPermission(String func) {
18939         int uid = Binder.getCallingUid();
18940         if (uid == Process.ROOT_UID) {
18941             return;
18942         }
18943
18944         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18945                 Settings.getPackageNameForUid(mContext, uid), false)) {
18946             return;
18947         }
18948
18949         String msg = "Permission Denial: " + func + " from pid="
18950                 + Binder.getCallingPid()
18951                 + ", uid=" + uid
18952                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18953         Slog.w(TAG, msg);
18954         throw new SecurityException(msg);
18955     }
18956
18957     public void updateConfiguration(Configuration values) {
18958         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18959                 "updateConfiguration()");
18960
18961         synchronized(this) {
18962             if (values == null && mWindowManager != null) {
18963                 // sentinel: fetch the current configuration from the window manager
18964                 values = mWindowManager.computeNewConfiguration();
18965             }
18966
18967             if (mWindowManager != null) {
18968                 mProcessList.applyDisplaySize(mWindowManager);
18969             }
18970
18971             final long origId = Binder.clearCallingIdentity();
18972             if (values != null) {
18973                 Settings.System.clearConfiguration(values);
18974             }
18975             updateConfigurationLocked(values, null, false);
18976             Binder.restoreCallingIdentity(origId);
18977         }
18978     }
18979
18980     void updateUserConfigurationLocked() {
18981         Configuration configuration = new Configuration(mConfiguration);
18982         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18983                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18984         updateConfigurationLocked(configuration, null, false);
18985     }
18986
18987     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18988             boolean initLocale) {
18989         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18990     }
18991
18992     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18993             boolean initLocale, boolean deferResume) {
18994         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18995         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18996                 UserHandle.USER_NULL, deferResume);
18997     }
18998
18999     // To cache the list of supported system locales
19000     private String[] mSupportedSystemLocales = null;
19001
19002     /**
19003      * Do either or both things: (1) change the current configuration, and (2)
19004      * make sure the given activity is running with the (now) current
19005      * configuration.  Returns true if the activity has been left running, or
19006      * false if <var>starting</var> is being destroyed to match the new
19007      * configuration.
19008      *
19009      * @param userId is only used when persistent parameter is set to true to persist configuration
19010      *               for that particular user
19011      */
19012     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19013             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19014         int changes = 0;
19015
19016         if (mWindowManager != null) {
19017             mWindowManager.deferSurfaceLayout();
19018         }
19019         if (values != null) {
19020             Configuration newConfig = new Configuration(mConfiguration);
19021             changes = newConfig.updateFrom(values);
19022             if (changes != 0) {
19023                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19024                         "Updating configuration to: " + values);
19025
19026                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19027
19028                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19029                     final LocaleList locales = values.getLocales();
19030                     int bestLocaleIndex = 0;
19031                     if (locales.size() > 1) {
19032                         if (mSupportedSystemLocales == null) {
19033                             mSupportedSystemLocales =
19034                                     Resources.getSystem().getAssets().getLocales();
19035                         }
19036                         bestLocaleIndex = Math.max(0,
19037                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
19038                     }
19039                     SystemProperties.set("persist.sys.locale",
19040                             locales.get(bestLocaleIndex).toLanguageTag());
19041                     LocaleList.setDefault(locales, bestLocaleIndex);
19042                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19043                             locales.get(bestLocaleIndex)));
19044                 }
19045
19046                 mConfigurationSeq++;
19047                 if (mConfigurationSeq <= 0) {
19048                     mConfigurationSeq = 1;
19049                 }
19050                 newConfig.seq = mConfigurationSeq;
19051                 mConfiguration = newConfig;
19052                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19053                 mUsageStatsService.reportConfigurationChange(newConfig,
19054                         mUserController.getCurrentUserIdLocked());
19055                 //mUsageStatsService.noteStartConfig(newConfig);
19056
19057                 final Configuration configCopy = new Configuration(mConfiguration);
19058
19059                 // TODO: If our config changes, should we auto dismiss any currently
19060                 // showing dialogs?
19061                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19062
19063                 AttributeCache ac = AttributeCache.instance();
19064                 if (ac != null) {
19065                     ac.updateConfiguration(configCopy);
19066                 }
19067
19068                 // Make sure all resources in our process are updated
19069                 // right now, so that anyone who is going to retrieve
19070                 // resource values after we return will be sure to get
19071                 // the new ones.  This is especially important during
19072                 // boot, where the first config change needs to guarantee
19073                 // all resources have that config before following boot
19074                 // code is executed.
19075                 mSystemThread.applyConfigurationToResources(configCopy);
19076
19077                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19078                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19079                     msg.obj = new Configuration(configCopy);
19080                     msg.arg1 = userId;
19081                     mHandler.sendMessage(msg);
19082                 }
19083
19084                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19085                 if (isDensityChange) {
19086                     // Reset the unsupported display size dialog.
19087                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19088
19089                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19090                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19091                 }
19092
19093                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19094                     ProcessRecord app = mLruProcesses.get(i);
19095                     try {
19096                         if (app.thread != null) {
19097                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19098                                     + app.processName + " new config " + mConfiguration);
19099                             app.thread.scheduleConfigurationChanged(configCopy);
19100                         }
19101                     } catch (Exception e) {
19102                     }
19103                 }
19104                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19105                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19106                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19107                         | Intent.FLAG_RECEIVER_FOREGROUND);
19108                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19109                         null, AppOpsManager.OP_NONE, null, false, false,
19110                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19111                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19112                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19113                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19114                     if (initLocale || !mProcessesReady) {
19115                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19116                     }
19117                     broadcastIntentLocked(null, null, intent,
19118                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19119                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19120                 }
19121             }
19122             // Update the configuration with WM first and check if any of the stacks need to be
19123             // resized due to the configuration change. If so, resize the stacks now and do any
19124             // relaunches if necessary. This way we don't need to relaunch again below in
19125             // ensureActivityConfigurationLocked().
19126             if (mWindowManager != null) {
19127                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19128                 if (resizedStacks != null) {
19129                     for (int stackId : resizedStacks) {
19130                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19131                         mStackSupervisor.resizeStackLocked(
19132                                 stackId, newBounds, null, null, false, false, deferResume);
19133                     }
19134                 }
19135             }
19136         }
19137
19138         boolean kept = true;
19139         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19140         // mainStack is null during startup.
19141         if (mainStack != null) {
19142             if (changes != 0 && starting == null) {
19143                 // If the configuration changed, and the caller is not already
19144                 // in the process of starting an activity, then find the top
19145                 // activity to check if its configuration needs to change.
19146                 starting = mainStack.topRunningActivityLocked();
19147             }
19148
19149             if (starting != null) {
19150                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19151                 // And we need to make sure at this point that all other activities
19152                 // are made visible with the correct configuration.
19153                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19154                         !PRESERVE_WINDOWS);
19155             }
19156         }
19157         if (mWindowManager != null) {
19158             mWindowManager.continueSurfaceLayout();
19159         }
19160         return kept;
19161     }
19162
19163     /**
19164      * Decide based on the configuration whether we should shouw the ANR,
19165      * crash, etc dialogs.  The idea is that if there is no affordence to
19166      * press the on-screen buttons, or the user experience would be more
19167      * greatly impacted than the crash itself, we shouldn't show the dialog.
19168      *
19169      * A thought: SystemUI might also want to get told about this, the Power
19170      * dialog / global actions also might want different behaviors.
19171      */
19172     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19173         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19174                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19175                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19176         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19177         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19178                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19179         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19180     }
19181
19182     @Override
19183     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19184         synchronized (this) {
19185             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19186             if (srec != null) {
19187                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19188             }
19189         }
19190         return false;
19191     }
19192
19193     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19194             Intent resultData) {
19195
19196         synchronized (this) {
19197             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19198             if (r != null) {
19199                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19200             }
19201             return false;
19202         }
19203     }
19204
19205     public int getLaunchedFromUid(IBinder activityToken) {
19206         ActivityRecord srec;
19207         synchronized (this) {
19208             srec = ActivityRecord.forTokenLocked(activityToken);
19209         }
19210         if (srec == null) {
19211             return -1;
19212         }
19213         return srec.launchedFromUid;
19214     }
19215
19216     public String getLaunchedFromPackage(IBinder activityToken) {
19217         ActivityRecord srec;
19218         synchronized (this) {
19219             srec = ActivityRecord.forTokenLocked(activityToken);
19220         }
19221         if (srec == null) {
19222             return null;
19223         }
19224         return srec.launchedFromPackage;
19225     }
19226
19227     // =========================================================
19228     // LIFETIME MANAGEMENT
19229     // =========================================================
19230
19231     // Returns which broadcast queue the app is the current [or imminent] receiver
19232     // on, or 'null' if the app is not an active broadcast recipient.
19233     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19234         BroadcastRecord r = app.curReceiver;
19235         if (r != null) {
19236             return r.queue;
19237         }
19238
19239         // It's not the current receiver, but it might be starting up to become one
19240         synchronized (this) {
19241             for (BroadcastQueue queue : mBroadcastQueues) {
19242                 r = queue.mPendingBroadcast;
19243                 if (r != null && r.curApp == app) {
19244                     // found it; report which queue it's in
19245                     return queue;
19246                 }
19247             }
19248         }
19249
19250         return null;
19251     }
19252
19253     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19254             int targetUid, ComponentName targetComponent, String targetProcess) {
19255         if (!mTrackingAssociations) {
19256             return null;
19257         }
19258         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19259                 = mAssociations.get(targetUid);
19260         if (components == null) {
19261             components = new ArrayMap<>();
19262             mAssociations.put(targetUid, components);
19263         }
19264         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19265         if (sourceUids == null) {
19266             sourceUids = new SparseArray<>();
19267             components.put(targetComponent, sourceUids);
19268         }
19269         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19270         if (sourceProcesses == null) {
19271             sourceProcesses = new ArrayMap<>();
19272             sourceUids.put(sourceUid, sourceProcesses);
19273         }
19274         Association ass = sourceProcesses.get(sourceProcess);
19275         if (ass == null) {
19276             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19277                     targetProcess);
19278             sourceProcesses.put(sourceProcess, ass);
19279         }
19280         ass.mCount++;
19281         ass.mNesting++;
19282         if (ass.mNesting == 1) {
19283             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19284             ass.mLastState = sourceState;
19285         }
19286         return ass;
19287     }
19288
19289     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19290             ComponentName targetComponent) {
19291         if (!mTrackingAssociations) {
19292             return;
19293         }
19294         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19295                 = mAssociations.get(targetUid);
19296         if (components == null) {
19297             return;
19298         }
19299         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19300         if (sourceUids == null) {
19301             return;
19302         }
19303         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19304         if (sourceProcesses == null) {
19305             return;
19306         }
19307         Association ass = sourceProcesses.get(sourceProcess);
19308         if (ass == null || ass.mNesting <= 0) {
19309             return;
19310         }
19311         ass.mNesting--;
19312         if (ass.mNesting == 0) {
19313             long uptime = SystemClock.uptimeMillis();
19314             ass.mTime += uptime - ass.mStartTime;
19315             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19316                     += uptime - ass.mLastStateUptime;
19317             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19318         }
19319     }
19320
19321     private void noteUidProcessState(final int uid, final int state) {
19322         mBatteryStatsService.noteUidProcessState(uid, state);
19323         if (mTrackingAssociations) {
19324             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19325                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19326                         = mAssociations.valueAt(i1);
19327                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19328                     SparseArray<ArrayMap<String, Association>> sourceUids
19329                             = targetComponents.valueAt(i2);
19330                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19331                     if (sourceProcesses != null) {
19332                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19333                             Association ass = sourceProcesses.valueAt(i4);
19334                             if (ass.mNesting >= 1) {
19335                                 // currently associated
19336                                 long uptime = SystemClock.uptimeMillis();
19337                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19338                                         += uptime - ass.mLastStateUptime;
19339                                 ass.mLastState = state;
19340                                 ass.mLastStateUptime = uptime;
19341                             }
19342                         }
19343                     }
19344                 }
19345             }
19346         }
19347     }
19348
19349     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19350             boolean doingAll, long now) {
19351         if (mAdjSeq == app.adjSeq) {
19352             // This adjustment has already been computed.
19353             return app.curRawAdj;
19354         }
19355
19356         if (app.thread == null) {
19357             app.adjSeq = mAdjSeq;
19358             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19359             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19360             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19361         }
19362
19363         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19364         app.adjSource = null;
19365         app.adjTarget = null;
19366         app.empty = false;
19367         app.cached = false;
19368
19369         final int activitiesSize = app.activities.size();
19370
19371         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19372             // The max adjustment doesn't allow this app to be anything
19373             // below foreground, so it is not worth doing work for it.
19374             app.adjType = "fixed";
19375             app.adjSeq = mAdjSeq;
19376             app.curRawAdj = app.maxAdj;
19377             app.foregroundActivities = false;
19378             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19379             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19380             // System processes can do UI, and when they do we want to have
19381             // them trim their memory after the user leaves the UI.  To
19382             // facilitate this, here we need to determine whether or not it
19383             // is currently showing UI.
19384             app.systemNoUi = true;
19385             if (app == TOP_APP) {
19386                 app.systemNoUi = false;
19387                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19388                 app.adjType = "pers-top-activity";
19389             } else if (app.hasTopUi) {
19390                 app.systemNoUi = false;
19391                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19392                 app.adjType = "pers-top-ui";
19393             } else if (activitiesSize > 0) {
19394                 for (int j = 0; j < activitiesSize; j++) {
19395                     final ActivityRecord r = app.activities.get(j);
19396                     if (r.visible) {
19397                         app.systemNoUi = false;
19398                     }
19399                 }
19400             }
19401             if (!app.systemNoUi) {
19402                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19403             }
19404             return (app.curAdj=app.maxAdj);
19405         }
19406
19407         app.systemNoUi = false;
19408
19409         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19410
19411         // Determine the importance of the process, starting with most
19412         // important to least, and assign an appropriate OOM adjustment.
19413         int adj;
19414         int schedGroup;
19415         int procState;
19416         boolean foregroundActivities = false;
19417         BroadcastQueue queue;
19418         if (app == TOP_APP) {
19419             // The last app on the list is the foreground app.
19420             adj = ProcessList.FOREGROUND_APP_ADJ;
19421             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19422             app.adjType = "top-activity";
19423             foregroundActivities = true;
19424             procState = PROCESS_STATE_CUR_TOP;
19425         } else if (app.instrumentationClass != null) {
19426             // Don't want to kill running instrumentation.
19427             adj = ProcessList.FOREGROUND_APP_ADJ;
19428             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19429             app.adjType = "instrumentation";
19430             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19431         } else if ((queue = isReceivingBroadcast(app)) != null) {
19432             // An app that is currently receiving a broadcast also
19433             // counts as being in the foreground for OOM killer purposes.
19434             // It's placed in a sched group based on the nature of the
19435             // broadcast as reflected by which queue it's active in.
19436             adj = ProcessList.FOREGROUND_APP_ADJ;
19437             schedGroup = (queue == mFgBroadcastQueue)
19438                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19439             app.adjType = "broadcast";
19440             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19441         } else if (app.executingServices.size() > 0) {
19442             // An app that is currently executing a service callback also
19443             // counts as being in the foreground.
19444             adj = ProcessList.FOREGROUND_APP_ADJ;
19445             schedGroup = app.execServicesFg ?
19446                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19447             app.adjType = "exec-service";
19448             procState = ActivityManager.PROCESS_STATE_SERVICE;
19449             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19450         } else {
19451             // As far as we know the process is empty.  We may change our mind later.
19452             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19453             // At this point we don't actually know the adjustment.  Use the cached adj
19454             // value that the caller wants us to.
19455             adj = cachedAdj;
19456             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19457             app.cached = true;
19458             app.empty = true;
19459             app.adjType = "cch-empty";
19460         }
19461
19462         // Examine all activities if not already foreground.
19463         if (!foregroundActivities && activitiesSize > 0) {
19464             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19465             for (int j = 0; j < activitiesSize; j++) {
19466                 final ActivityRecord r = app.activities.get(j);
19467                 if (r.app != app) {
19468                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19469                             + " instead of expected " + app);
19470                     if (r.app == null || (r.app.uid == app.uid)) {
19471                         // Only fix things up when they look sane
19472                         r.app = app;
19473                     } else {
19474                         continue;
19475                     }
19476                 }
19477                 if (r.visible) {
19478                     // App has a visible activity; only upgrade adjustment.
19479                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19480                         adj = ProcessList.VISIBLE_APP_ADJ;
19481                         app.adjType = "visible";
19482                     }
19483                     if (procState > PROCESS_STATE_CUR_TOP) {
19484                         procState = PROCESS_STATE_CUR_TOP;
19485                     }
19486                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19487                     app.cached = false;
19488                     app.empty = false;
19489                     foregroundActivities = true;
19490                     if (r.task != null && minLayer > 0) {
19491                         final int layer = r.task.mLayerRank;
19492                         if (layer >= 0 && minLayer > layer) {
19493                             minLayer = layer;
19494                         }
19495                     }
19496                     break;
19497                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19498                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19499                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19500                         app.adjType = "pausing";
19501                     }
19502                     if (procState > PROCESS_STATE_CUR_TOP) {
19503                         procState = PROCESS_STATE_CUR_TOP;
19504                     }
19505                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19506                     app.cached = false;
19507                     app.empty = false;
19508                     foregroundActivities = true;
19509                 } else if (r.state == ActivityState.STOPPING) {
19510                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19511                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19512                         app.adjType = "stopping";
19513                     }
19514                     // For the process state, we will at this point consider the
19515                     // process to be cached.  It will be cached either as an activity
19516                     // or empty depending on whether the activity is finishing.  We do
19517                     // this so that we can treat the process as cached for purposes of
19518                     // memory trimming (determing current memory level, trim command to
19519                     // send to process) since there can be an arbitrary number of stopping
19520                     // processes and they should soon all go into the cached state.
19521                     if (!r.finishing) {
19522                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19523                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19524                         }
19525                     }
19526                     app.cached = false;
19527                     app.empty = false;
19528                     foregroundActivities = true;
19529                 } else {
19530                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19531                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19532                         app.adjType = "cch-act";
19533                     }
19534                 }
19535             }
19536             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19537                 adj += minLayer;
19538             }
19539         }
19540
19541         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19542                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19543             if (app.foregroundServices) {
19544                 // The user is aware of this app, so make it visible.
19545                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19546                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19547                 app.cached = false;
19548                 app.adjType = "fg-service";
19549                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19550             } else if (app.forcingToForeground != null) {
19551                 // The user is aware of this app, so make it visible.
19552                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19553                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19554                 app.cached = false;
19555                 app.adjType = "force-fg";
19556                 app.adjSource = app.forcingToForeground;
19557                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19558             }
19559         }
19560
19561         if (app == mHeavyWeightProcess) {
19562             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19563                 // We don't want to kill the current heavy-weight process.
19564                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19565                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19566                 app.cached = false;
19567                 app.adjType = "heavy";
19568             }
19569             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19570                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19571             }
19572         }
19573
19574         if (app == mHomeProcess) {
19575             if (adj > ProcessList.HOME_APP_ADJ) {
19576                 // This process is hosting what we currently consider to be the
19577                 // home app, so we don't want to let it go into the background.
19578                 adj = ProcessList.HOME_APP_ADJ;
19579                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19580                 app.cached = false;
19581                 app.adjType = "home";
19582             }
19583             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19584                 procState = ActivityManager.PROCESS_STATE_HOME;
19585             }
19586         }
19587
19588         if (app == mPreviousProcess && app.activities.size() > 0) {
19589             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19590                 // This was the previous process that showed UI to the user.
19591                 // We want to try to keep it around more aggressively, to give
19592                 // a good experience around switching between two apps.
19593                 adj = ProcessList.PREVIOUS_APP_ADJ;
19594                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19595                 app.cached = false;
19596                 app.adjType = "previous";
19597             }
19598             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19599                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19600             }
19601         }
19602
19603         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19604                 + " reason=" + app.adjType);
19605
19606         // By default, we use the computed adjustment.  It may be changed if
19607         // there are applications dependent on our services or providers, but
19608         // this gives us a baseline and makes sure we don't get into an
19609         // infinite recursion.
19610         app.adjSeq = mAdjSeq;
19611         app.curRawAdj = adj;
19612         app.hasStartedServices = false;
19613
19614         if (mBackupTarget != null && app == mBackupTarget.app) {
19615             // If possible we want to avoid killing apps while they're being backed up
19616             if (adj > ProcessList.BACKUP_APP_ADJ) {
19617                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19618                 adj = ProcessList.BACKUP_APP_ADJ;
19619                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19620                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19621                 }
19622                 app.adjType = "backup";
19623                 app.cached = false;
19624             }
19625             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19626                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19627             }
19628         }
19629
19630         boolean mayBeTop = false;
19631
19632         for (int is = app.services.size()-1;
19633                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19634                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19635                         || procState > ActivityManager.PROCESS_STATE_TOP);
19636                 is--) {
19637             ServiceRecord s = app.services.valueAt(is);
19638             if (s.startRequested) {
19639                 app.hasStartedServices = true;
19640                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19641                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19642                 }
19643                 if (app.hasShownUi && app != mHomeProcess) {
19644                     // If this process has shown some UI, let it immediately
19645                     // go to the LRU list because it may be pretty heavy with
19646                     // UI stuff.  We'll tag it with a label just to help
19647                     // debug and understand what is going on.
19648                     if (adj > ProcessList.SERVICE_ADJ) {
19649                         app.adjType = "cch-started-ui-services";
19650                     }
19651                 } else {
19652                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19653                         // This service has seen some activity within
19654                         // recent memory, so we will keep its process ahead
19655                         // of the background processes.
19656                         if (adj > ProcessList.SERVICE_ADJ) {
19657                             adj = ProcessList.SERVICE_ADJ;
19658                             app.adjType = "started-services";
19659                             app.cached = false;
19660                         }
19661                     }
19662                     // If we have let the service slide into the background
19663                     // state, still have some text describing what it is doing
19664                     // even though the service no longer has an impact.
19665                     if (adj > ProcessList.SERVICE_ADJ) {
19666                         app.adjType = "cch-started-services";
19667                     }
19668                 }
19669             }
19670
19671             for (int conni = s.connections.size()-1;
19672                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19673                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19674                             || procState > ActivityManager.PROCESS_STATE_TOP);
19675                     conni--) {
19676                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19677                 for (int i = 0;
19678                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19679                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19680                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19681                         i++) {
19682                     // XXX should compute this based on the max of
19683                     // all connected clients.
19684                     ConnectionRecord cr = clist.get(i);
19685                     if (cr.binding.client == app) {
19686                         // Binding to ourself is not interesting.
19687                         continue;
19688                     }
19689
19690                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19691                         ProcessRecord client = cr.binding.client;
19692                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19693                                 TOP_APP, doingAll, now);
19694                         int clientProcState = client.curProcState;
19695                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19696                             // If the other app is cached for any reason, for purposes here
19697                             // we are going to consider it empty.  The specific cached state
19698                             // doesn't propagate except under certain conditions.
19699                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19700                         }
19701                         String adjType = null;
19702                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19703                             // Not doing bind OOM management, so treat
19704                             // this guy more like a started service.
19705                             if (app.hasShownUi && app != mHomeProcess) {
19706                                 // If this process has shown some UI, let it immediately
19707                                 // go to the LRU list because it may be pretty heavy with
19708                                 // UI stuff.  We'll tag it with a label just to help
19709                                 // debug and understand what is going on.
19710                                 if (adj > clientAdj) {
19711                                     adjType = "cch-bound-ui-services";
19712                                 }
19713                                 app.cached = false;
19714                                 clientAdj = adj;
19715                                 clientProcState = procState;
19716                             } else {
19717                                 if (now >= (s.lastActivity
19718                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19719                                     // This service has not seen activity within
19720                                     // recent memory, so allow it to drop to the
19721                                     // LRU list if there is no other reason to keep
19722                                     // it around.  We'll also tag it with a label just
19723                                     // to help debug and undertand what is going on.
19724                                     if (adj > clientAdj) {
19725                                         adjType = "cch-bound-services";
19726                                     }
19727                                     clientAdj = adj;
19728                                 }
19729                             }
19730                         }
19731                         if (adj > clientAdj) {
19732                             // If this process has recently shown UI, and
19733                             // the process that is binding to it is less
19734                             // important than being visible, then we don't
19735                             // care about the binding as much as we care
19736                             // about letting this process get into the LRU
19737                             // list to be killed and restarted if needed for
19738                             // memory.
19739                             if (app.hasShownUi && app != mHomeProcess
19740                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19741                                 adjType = "cch-bound-ui-services";
19742                             } else {
19743                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19744                                         |Context.BIND_IMPORTANT)) != 0) {
19745                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19746                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19747                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19748                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19749                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19750                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19751                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19752                                     adj = clientAdj;
19753                                 } else {
19754                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19755                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19756                                     }
19757                                 }
19758                                 if (!client.cached) {
19759                                     app.cached = false;
19760                                 }
19761                                 adjType = "service";
19762                             }
19763                         }
19764                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19765                             // This will treat important bound services identically to
19766                             // the top app, which may behave differently than generic
19767                             // foreground work.
19768                             if (client.curSchedGroup > schedGroup) {
19769                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19770                                     schedGroup = client.curSchedGroup;
19771                                 } else {
19772                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19773                                 }
19774                             }
19775                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19776                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19777                                     // Special handling of clients who are in the top state.
19778                                     // We *may* want to consider this process to be in the
19779                                     // top state as well, but only if there is not another
19780                                     // reason for it to be running.  Being on the top is a
19781                                     // special state, meaning you are specifically running
19782                                     // for the current top app.  If the process is already
19783                                     // running in the background for some other reason, it
19784                                     // is more important to continue considering it to be
19785                                     // in the background state.
19786                                     mayBeTop = true;
19787                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19788                                 } else {
19789                                     // Special handling for above-top states (persistent
19790                                     // processes).  These should not bring the current process
19791                                     // into the top state, since they are not on top.  Instead
19792                                     // give them the best state after that.
19793                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19794                                         clientProcState =
19795                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19796                                     } else if (mWakefulness
19797                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19798                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19799                                                     != 0) {
19800                                         clientProcState =
19801                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19802                                     } else {
19803                                         clientProcState =
19804                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19805                                     }
19806                                 }
19807                             }
19808                         } else {
19809                             if (clientProcState <
19810                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19811                                 clientProcState =
19812                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19813                             }
19814                         }
19815                         if (procState > clientProcState) {
19816                             procState = clientProcState;
19817                         }
19818                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19819                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19820                             app.pendingUiClean = true;
19821                         }
19822                         if (adjType != null) {
19823                             app.adjType = adjType;
19824                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19825                                     .REASON_SERVICE_IN_USE;
19826                             app.adjSource = cr.binding.client;
19827                             app.adjSourceProcState = clientProcState;
19828                             app.adjTarget = s.name;
19829                         }
19830                     }
19831                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19832                         app.treatLikeActivity = true;
19833                     }
19834                     final ActivityRecord a = cr.activity;
19835                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19836                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19837                             (a.visible || a.state == ActivityState.RESUMED ||
19838                              a.state == ActivityState.PAUSING)) {
19839                             adj = ProcessList.FOREGROUND_APP_ADJ;
19840                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19841                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19842                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19843                                 } else {
19844                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19845                                 }
19846                             }
19847                             app.cached = false;
19848                             app.adjType = "service";
19849                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19850                                     .REASON_SERVICE_IN_USE;
19851                             app.adjSource = a;
19852                             app.adjSourceProcState = procState;
19853                             app.adjTarget = s.name;
19854                         }
19855                     }
19856                 }
19857             }
19858         }
19859
19860         for (int provi = app.pubProviders.size()-1;
19861                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19862                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19863                         || procState > ActivityManager.PROCESS_STATE_TOP);
19864                 provi--) {
19865             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19866             for (int i = cpr.connections.size()-1;
19867                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19868                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19869                             || procState > ActivityManager.PROCESS_STATE_TOP);
19870                     i--) {
19871                 ContentProviderConnection conn = cpr.connections.get(i);
19872                 ProcessRecord client = conn.client;
19873                 if (client == app) {
19874                     // Being our own client is not interesting.
19875                     continue;
19876                 }
19877                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19878                 int clientProcState = client.curProcState;
19879                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19880                     // If the other app is cached for any reason, for purposes here
19881                     // we are going to consider it empty.
19882                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19883                 }
19884                 if (adj > clientAdj) {
19885                     if (app.hasShownUi && app != mHomeProcess
19886                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19887                         app.adjType = "cch-ui-provider";
19888                     } else {
19889                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19890                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19891                         app.adjType = "provider";
19892                     }
19893                     app.cached &= client.cached;
19894                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19895                             .REASON_PROVIDER_IN_USE;
19896                     app.adjSource = client;
19897                     app.adjSourceProcState = clientProcState;
19898                     app.adjTarget = cpr.name;
19899                 }
19900                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19901                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19902                         // Special handling of clients who are in the top state.
19903                         // We *may* want to consider this process to be in the
19904                         // top state as well, but only if there is not another
19905                         // reason for it to be running.  Being on the top is a
19906                         // special state, meaning you are specifically running
19907                         // for the current top app.  If the process is already
19908                         // running in the background for some other reason, it
19909                         // is more important to continue considering it to be
19910                         // in the background state.
19911                         mayBeTop = true;
19912                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19913                     } else {
19914                         // Special handling for above-top states (persistent
19915                         // processes).  These should not bring the current process
19916                         // into the top state, since they are not on top.  Instead
19917                         // give them the best state after that.
19918                         clientProcState =
19919                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19920                     }
19921                 }
19922                 if (procState > clientProcState) {
19923                     procState = clientProcState;
19924                 }
19925                 if (client.curSchedGroup > schedGroup) {
19926                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19927                 }
19928             }
19929             // If the provider has external (non-framework) process
19930             // dependencies, ensure that its adjustment is at least
19931             // FOREGROUND_APP_ADJ.
19932             if (cpr.hasExternalProcessHandles()) {
19933                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19934                     adj = ProcessList.FOREGROUND_APP_ADJ;
19935                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19936                     app.cached = false;
19937                     app.adjType = "provider";
19938                     app.adjTarget = cpr.name;
19939                 }
19940                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19941                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19942                 }
19943             }
19944         }
19945
19946         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19947             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19948                 adj = ProcessList.PREVIOUS_APP_ADJ;
19949                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19950                 app.cached = false;
19951                 app.adjType = "provider";
19952             }
19953             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19954                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19955             }
19956         }
19957
19958         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19959             // A client of one of our services or providers is in the top state.  We
19960             // *may* want to be in the top state, but not if we are already running in
19961             // the background for some other reason.  For the decision here, we are going
19962             // to pick out a few specific states that we want to remain in when a client
19963             // is top (states that tend to be longer-term) and otherwise allow it to go
19964             // to the top state.
19965             switch (procState) {
19966                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19967                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19968                 case ActivityManager.PROCESS_STATE_SERVICE:
19969                     // These all are longer-term states, so pull them up to the top
19970                     // of the background states, but not all the way to the top state.
19971                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19972                     break;
19973                 default:
19974                     // Otherwise, top is a better choice, so take it.
19975                     procState = ActivityManager.PROCESS_STATE_TOP;
19976                     break;
19977             }
19978         }
19979
19980         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19981             if (app.hasClientActivities) {
19982                 // This is a cached process, but with client activities.  Mark it so.
19983                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19984                 app.adjType = "cch-client-act";
19985             } else if (app.treatLikeActivity) {
19986                 // This is a cached process, but somebody wants us to treat it like it has
19987                 // an activity, okay!
19988                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19989                 app.adjType = "cch-as-act";
19990             }
19991         }
19992
19993         if (adj == ProcessList.SERVICE_ADJ) {
19994             if (doingAll) {
19995                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19996                 mNewNumServiceProcs++;
19997                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19998                 if (!app.serviceb) {
19999                     // This service isn't far enough down on the LRU list to
20000                     // normally be a B service, but if we are low on RAM and it
20001                     // is large we want to force it down since we would prefer to
20002                     // keep launcher over it.
20003                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20004                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20005                         app.serviceHighRam = true;
20006                         app.serviceb = true;
20007                         //Slog.i(TAG, "ADJ " + app + " high ram!");
20008                     } else {
20009                         mNewNumAServiceProcs++;
20010                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
20011                     }
20012                 } else {
20013                     app.serviceHighRam = false;
20014                 }
20015             }
20016             if (app.serviceb) {
20017                 adj = ProcessList.SERVICE_B_ADJ;
20018             }
20019         }
20020
20021         app.curRawAdj = adj;
20022
20023         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20024         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20025         if (adj > app.maxAdj) {
20026             adj = app.maxAdj;
20027             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20028                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20029             }
20030         }
20031
20032         // Do final modification to adj.  Everything we do between here and applying
20033         // the final setAdj must be done in this function, because we will also use
20034         // it when computing the final cached adj later.  Note that we don't need to
20035         // worry about this for max adj above, since max adj will always be used to
20036         // keep it out of the cached vaues.
20037         app.curAdj = app.modifyRawOomAdj(adj);
20038         app.curSchedGroup = schedGroup;
20039         app.curProcState = procState;
20040         app.foregroundActivities = foregroundActivities;
20041
20042         return app.curRawAdj;
20043     }
20044
20045     /**
20046      * Record new PSS sample for a process.
20047      */
20048     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20049             long now) {
20050         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20051                 swapPss * 1024);
20052         proc.lastPssTime = now;
20053         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20054         if (DEBUG_PSS) Slog.d(TAG_PSS,
20055                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20056                 + " state=" + ProcessList.makeProcStateString(procState));
20057         if (proc.initialIdlePss == 0) {
20058             proc.initialIdlePss = pss;
20059         }
20060         proc.lastPss = pss;
20061         proc.lastSwapPss = swapPss;
20062         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20063             proc.lastCachedPss = pss;
20064             proc.lastCachedSwapPss = swapPss;
20065         }
20066
20067         final SparseArray<Pair<Long, String>> watchUids
20068                 = mMemWatchProcesses.getMap().get(proc.processName);
20069         Long check = null;
20070         if (watchUids != null) {
20071             Pair<Long, String> val = watchUids.get(proc.uid);
20072             if (val == null) {
20073                 val = watchUids.get(0);
20074             }
20075             if (val != null) {
20076                 check = val.first;
20077             }
20078         }
20079         if (check != null) {
20080             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20081                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20082                 if (!isDebuggable) {
20083                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20084                         isDebuggable = true;
20085                     }
20086                 }
20087                 if (isDebuggable) {
20088                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20089                     final ProcessRecord myProc = proc;
20090                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20091                     mMemWatchDumpProcName = proc.processName;
20092                     mMemWatchDumpFile = heapdumpFile.toString();
20093                     mMemWatchDumpPid = proc.pid;
20094                     mMemWatchDumpUid = proc.uid;
20095                     BackgroundThread.getHandler().post(new Runnable() {
20096                         @Override
20097                         public void run() {
20098                             revokeUriPermission(ActivityThread.currentActivityThread()
20099                                             .getApplicationThread(),
20100                                     DumpHeapActivity.JAVA_URI,
20101                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20102                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20103                                     UserHandle.myUserId());
20104                             ParcelFileDescriptor fd = null;
20105                             try {
20106                                 heapdumpFile.delete();
20107                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20108                                         ParcelFileDescriptor.MODE_CREATE |
20109                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20110                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20111                                                 ParcelFileDescriptor.MODE_APPEND);
20112                                 IApplicationThread thread = myProc.thread;
20113                                 if (thread != null) {
20114                                     try {
20115                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20116                                                 "Requesting dump heap from "
20117                                                 + myProc + " to " + heapdumpFile);
20118                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20119                                     } catch (RemoteException e) {
20120                                     }
20121                                 }
20122                             } catch (FileNotFoundException e) {
20123                                 e.printStackTrace();
20124                             } finally {
20125                                 if (fd != null) {
20126                                     try {
20127                                         fd.close();
20128                                     } catch (IOException e) {
20129                                     }
20130                                 }
20131                             }
20132                         }
20133                     });
20134                 } else {
20135                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20136                             + ", but debugging not enabled");
20137                 }
20138             }
20139         }
20140     }
20141
20142     /**
20143      * Schedule PSS collection of a process.
20144      */
20145     void requestPssLocked(ProcessRecord proc, int procState) {
20146         if (mPendingPssProcesses.contains(proc)) {
20147             return;
20148         }
20149         if (mPendingPssProcesses.size() == 0) {
20150             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20151         }
20152         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20153         proc.pssProcState = procState;
20154         mPendingPssProcesses.add(proc);
20155     }
20156
20157     /**
20158      * Schedule PSS collection of all processes.
20159      */
20160     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20161         if (!always) {
20162             if (now < (mLastFullPssTime +
20163                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20164                 return;
20165             }
20166         }
20167         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20168         mLastFullPssTime = now;
20169         mFullPssPending = true;
20170         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20171         mPendingPssProcesses.clear();
20172         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20173             ProcessRecord app = mLruProcesses.get(i);
20174             if (app.thread == null
20175                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20176                 continue;
20177             }
20178             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20179                 app.pssProcState = app.setProcState;
20180                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20181                         mTestPssMode, isSleepingLocked(), now);
20182                 mPendingPssProcesses.add(app);
20183             }
20184         }
20185         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20186     }
20187
20188     public void setTestPssMode(boolean enabled) {
20189         synchronized (this) {
20190             mTestPssMode = enabled;
20191             if (enabled) {
20192                 // Whenever we enable the mode, we want to take a snapshot all of current
20193                 // process mem use.
20194                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20195             }
20196         }
20197     }
20198
20199     /**
20200      * Ask a given process to GC right now.
20201      */
20202     final void performAppGcLocked(ProcessRecord app) {
20203         try {
20204             app.lastRequestedGc = SystemClock.uptimeMillis();
20205             if (app.thread != null) {
20206                 if (app.reportLowMemory) {
20207                     app.reportLowMemory = false;
20208                     app.thread.scheduleLowMemory();
20209                 } else {
20210                     app.thread.processInBackground();
20211                 }
20212             }
20213         } catch (Exception e) {
20214             // whatever.
20215         }
20216     }
20217
20218     /**
20219      * Returns true if things are idle enough to perform GCs.
20220      */
20221     private final boolean canGcNowLocked() {
20222         boolean processingBroadcasts = false;
20223         for (BroadcastQueue q : mBroadcastQueues) {
20224             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20225                 processingBroadcasts = true;
20226             }
20227         }
20228         return !processingBroadcasts
20229                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20230     }
20231
20232     /**
20233      * Perform GCs on all processes that are waiting for it, but only
20234      * if things are idle.
20235      */
20236     final void performAppGcsLocked() {
20237         final int N = mProcessesToGc.size();
20238         if (N <= 0) {
20239             return;
20240         }
20241         if (canGcNowLocked()) {
20242             while (mProcessesToGc.size() > 0) {
20243                 ProcessRecord proc = mProcessesToGc.remove(0);
20244                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20245                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20246                             <= SystemClock.uptimeMillis()) {
20247                         // To avoid spamming the system, we will GC processes one
20248                         // at a time, waiting a few seconds between each.
20249                         performAppGcLocked(proc);
20250                         scheduleAppGcsLocked();
20251                         return;
20252                     } else {
20253                         // It hasn't been long enough since we last GCed this
20254                         // process...  put it in the list to wait for its time.
20255                         addProcessToGcListLocked(proc);
20256                         break;
20257                     }
20258                 }
20259             }
20260
20261             scheduleAppGcsLocked();
20262         }
20263     }
20264
20265     /**
20266      * If all looks good, perform GCs on all processes waiting for them.
20267      */
20268     final void performAppGcsIfAppropriateLocked() {
20269         if (canGcNowLocked()) {
20270             performAppGcsLocked();
20271             return;
20272         }
20273         // Still not idle, wait some more.
20274         scheduleAppGcsLocked();
20275     }
20276
20277     /**
20278      * Schedule the execution of all pending app GCs.
20279      */
20280     final void scheduleAppGcsLocked() {
20281         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20282
20283         if (mProcessesToGc.size() > 0) {
20284             // Schedule a GC for the time to the next process.
20285             ProcessRecord proc = mProcessesToGc.get(0);
20286             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20287
20288             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20289             long now = SystemClock.uptimeMillis();
20290             if (when < (now+GC_TIMEOUT)) {
20291                 when = now + GC_TIMEOUT;
20292             }
20293             mHandler.sendMessageAtTime(msg, when);
20294         }
20295     }
20296
20297     /**
20298      * Add a process to the array of processes waiting to be GCed.  Keeps the
20299      * list in sorted order by the last GC time.  The process can't already be
20300      * on the list.
20301      */
20302     final void addProcessToGcListLocked(ProcessRecord proc) {
20303         boolean added = false;
20304         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20305             if (mProcessesToGc.get(i).lastRequestedGc <
20306                     proc.lastRequestedGc) {
20307                 added = true;
20308                 mProcessesToGc.add(i+1, proc);
20309                 break;
20310             }
20311         }
20312         if (!added) {
20313             mProcessesToGc.add(0, proc);
20314         }
20315     }
20316
20317     /**
20318      * Set up to ask a process to GC itself.  This will either do it
20319      * immediately, or put it on the list of processes to gc the next
20320      * time things are idle.
20321      */
20322     final void scheduleAppGcLocked(ProcessRecord app) {
20323         long now = SystemClock.uptimeMillis();
20324         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20325             return;
20326         }
20327         if (!mProcessesToGc.contains(app)) {
20328             addProcessToGcListLocked(app);
20329             scheduleAppGcsLocked();
20330         }
20331     }
20332
20333     final void checkExcessivePowerUsageLocked(boolean doKills) {
20334         updateCpuStatsNow();
20335
20336         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20337         boolean doWakeKills = doKills;
20338         boolean doCpuKills = doKills;
20339         if (mLastPowerCheckRealtime == 0) {
20340             doWakeKills = false;
20341         }
20342         if (mLastPowerCheckUptime == 0) {
20343             doCpuKills = false;
20344         }
20345         if (stats.isScreenOn()) {
20346             doWakeKills = false;
20347         }
20348         final long curRealtime = SystemClock.elapsedRealtime();
20349         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20350         final long curUptime = SystemClock.uptimeMillis();
20351         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20352         mLastPowerCheckRealtime = curRealtime;
20353         mLastPowerCheckUptime = curUptime;
20354         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20355             doWakeKills = false;
20356         }
20357         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20358             doCpuKills = false;
20359         }
20360         int i = mLruProcesses.size();
20361         while (i > 0) {
20362             i--;
20363             ProcessRecord app = mLruProcesses.get(i);
20364             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20365                 long wtime;
20366                 synchronized (stats) {
20367                     wtime = stats.getProcessWakeTime(app.info.uid,
20368                             app.pid, curRealtime);
20369                 }
20370                 long wtimeUsed = wtime - app.lastWakeTime;
20371                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20372                 if (DEBUG_POWER) {
20373                     StringBuilder sb = new StringBuilder(128);
20374                     sb.append("Wake for ");
20375                     app.toShortString(sb);
20376                     sb.append(": over ");
20377                     TimeUtils.formatDuration(realtimeSince, sb);
20378                     sb.append(" used ");
20379                     TimeUtils.formatDuration(wtimeUsed, sb);
20380                     sb.append(" (");
20381                     sb.append((wtimeUsed*100)/realtimeSince);
20382                     sb.append("%)");
20383                     Slog.i(TAG_POWER, sb.toString());
20384                     sb.setLength(0);
20385                     sb.append("CPU for ");
20386                     app.toShortString(sb);
20387                     sb.append(": over ");
20388                     TimeUtils.formatDuration(uptimeSince, sb);
20389                     sb.append(" used ");
20390                     TimeUtils.formatDuration(cputimeUsed, sb);
20391                     sb.append(" (");
20392                     sb.append((cputimeUsed*100)/uptimeSince);
20393                     sb.append("%)");
20394                     Slog.i(TAG_POWER, sb.toString());
20395                 }
20396                 // If a process has held a wake lock for more
20397                 // than 50% of the time during this period,
20398                 // that sounds bad.  Kill!
20399                 if (doWakeKills && realtimeSince > 0
20400                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20401                     synchronized (stats) {
20402                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20403                                 realtimeSince, wtimeUsed);
20404                     }
20405                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20406                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20407                 } else if (doCpuKills && uptimeSince > 0
20408                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20409                     synchronized (stats) {
20410                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20411                                 uptimeSince, cputimeUsed);
20412                     }
20413                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20414                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20415                 } else {
20416                     app.lastWakeTime = wtime;
20417                     app.lastCpuTime = app.curCpuTime;
20418                 }
20419             }
20420         }
20421     }
20422
20423     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20424             long nowElapsed) {
20425         boolean success = true;
20426
20427         if (app.curRawAdj != app.setRawAdj) {
20428             app.setRawAdj = app.curRawAdj;
20429         }
20430
20431         int changes = 0;
20432
20433         if (app.curAdj != app.setAdj) {
20434             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20435             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20436                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20437                     + app.adjType);
20438             app.setAdj = app.curAdj;
20439             app.verifiedAdj = ProcessList.INVALID_ADJ;
20440         }
20441
20442         if (app.setSchedGroup != app.curSchedGroup) {
20443             int oldSchedGroup = app.setSchedGroup;
20444             app.setSchedGroup = app.curSchedGroup;
20445             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20446                     "Setting sched group of " + app.processName
20447                     + " to " + app.curSchedGroup);
20448             if (app.waitingToKill != null && app.curReceiver == null
20449                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20450                 app.kill(app.waitingToKill, true);
20451                 success = false;
20452             } else {
20453                 int processGroup;
20454                 switch (app.curSchedGroup) {
20455                     case ProcessList.SCHED_GROUP_BACKGROUND:
20456                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20457                         break;
20458                     case ProcessList.SCHED_GROUP_TOP_APP:
20459                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20460                         processGroup = Process.THREAD_GROUP_TOP_APP;
20461                         break;
20462                     default:
20463                         processGroup = Process.THREAD_GROUP_DEFAULT;
20464                         break;
20465                 }
20466                 long oldId = Binder.clearCallingIdentity();
20467                 try {
20468                     Process.setProcessGroup(app.pid, processGroup);
20469                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20470                         // do nothing if we already switched to RT
20471                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20472                             // Switch VR thread for app to SCHED_FIFO
20473                             if (mInVrMode && app.vrThreadTid != 0) {
20474                                 try {
20475                                     Process.setThreadScheduler(app.vrThreadTid,
20476                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20477                                 } catch (IllegalArgumentException e) {
20478                                     // thread died, ignore
20479                                 }
20480                             }
20481                             if (mUseFifoUiScheduling) {
20482                                 // Switch UI pipeline for app to SCHED_FIFO
20483                                 app.savedPriority = Process.getThreadPriority(app.pid);
20484                                 try {
20485                                     Process.setThreadScheduler(app.pid,
20486                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20487                                 } catch (IllegalArgumentException e) {
20488                                     // thread died, ignore
20489                                 }
20490                                 if (app.renderThreadTid != 0) {
20491                                     try {
20492                                         Process.setThreadScheduler(app.renderThreadTid,
20493                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20494                                     } catch (IllegalArgumentException e) {
20495                                         // thread died, ignore
20496                                     }
20497                                     if (DEBUG_OOM_ADJ) {
20498                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20499                                             app.renderThreadTid + ") to FIFO");
20500                                     }
20501                                 } else {
20502                                     if (DEBUG_OOM_ADJ) {
20503                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20504                                     }
20505                                 }
20506                             } else {
20507                                 // Boost priority for top app UI and render threads
20508                                 Process.setThreadPriority(app.pid, -10);
20509                                 if (app.renderThreadTid != 0) {
20510                                     try {
20511                                         Process.setThreadPriority(app.renderThreadTid, -10);
20512                                     } catch (IllegalArgumentException e) {
20513                                         // thread died, ignore
20514                                     }
20515                                 }
20516                             }
20517                         }
20518                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20519                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20520                         // Reset VR thread to SCHED_OTHER
20521                         // Safe to do even if we're not in VR mode
20522                         if (app.vrThreadTid != 0) {
20523                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20524                         }
20525                         if (mUseFifoUiScheduling) {
20526                             // Reset UI pipeline to SCHED_OTHER
20527                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20528                             Process.setThreadPriority(app.pid, app.savedPriority);
20529                             if (app.renderThreadTid != 0) {
20530                                 Process.setThreadScheduler(app.renderThreadTid,
20531                                     Process.SCHED_OTHER, 0);
20532                                 Process.setThreadPriority(app.renderThreadTid, -4);
20533                             }
20534                         } else {
20535                             // Reset priority for top app UI and render threads
20536                             Process.setThreadPriority(app.pid, 0);
20537                             if (app.renderThreadTid != 0) {
20538                                 Process.setThreadPriority(app.renderThreadTid, 0);
20539                             }
20540                         }
20541                     }
20542                 } catch (Exception e) {
20543                     Slog.w(TAG, "Failed setting process group of " + app.pid
20544                             + " to " + app.curSchedGroup);
20545                     e.printStackTrace();
20546                 } finally {
20547                     Binder.restoreCallingIdentity(oldId);
20548                 }
20549             }
20550         }
20551         if (app.repForegroundActivities != app.foregroundActivities) {
20552             app.repForegroundActivities = app.foregroundActivities;
20553             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20554         }
20555         if (app.repProcState != app.curProcState) {
20556             app.repProcState = app.curProcState;
20557             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20558             if (app.thread != null) {
20559                 try {
20560                     if (false) {
20561                         //RuntimeException h = new RuntimeException("here");
20562                         Slog.i(TAG, "Sending new process state " + app.repProcState
20563                                 + " to " + app /*, h*/);
20564                     }
20565                     app.thread.setProcessState(app.repProcState);
20566                 } catch (RemoteException e) {
20567                 }
20568             }
20569         }
20570         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20571                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20572             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20573                 // Experimental code to more aggressively collect pss while
20574                 // running test...  the problem is that this tends to collect
20575                 // the data right when a process is transitioning between process
20576                 // states, which well tend to give noisy data.
20577                 long start = SystemClock.uptimeMillis();
20578                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20579                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20580                 mPendingPssProcesses.remove(app);
20581                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20582                         + " to " + app.curProcState + ": "
20583                         + (SystemClock.uptimeMillis()-start) + "ms");
20584             }
20585             app.lastStateTime = now;
20586             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20587                     mTestPssMode, isSleepingLocked(), now);
20588             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20589                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20590                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20591                     + (app.nextPssTime-now) + ": " + app);
20592         } else {
20593             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20594                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20595                     mTestPssMode)))) {
20596                 requestPssLocked(app, app.setProcState);
20597                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20598                         mTestPssMode, isSleepingLocked(), now);
20599             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20600                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20601         }
20602         if (app.setProcState != app.curProcState) {
20603             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20604                     "Proc state change of " + app.processName
20605                             + " to " + app.curProcState);
20606             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20607             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20608             if (setImportant && !curImportant) {
20609                 // This app is no longer something we consider important enough to allow to
20610                 // use arbitrary amounts of battery power.  Note
20611                 // its current wake lock time to later know to kill it if
20612                 // it is not behaving well.
20613                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20614                 synchronized (stats) {
20615                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20616                             app.pid, nowElapsed);
20617                 }
20618                 app.lastCpuTime = app.curCpuTime;
20619
20620             }
20621             // Inform UsageStats of important process state change
20622             // Must be called before updating setProcState
20623             maybeUpdateUsageStatsLocked(app, nowElapsed);
20624
20625             app.setProcState = app.curProcState;
20626             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20627                 app.notCachedSinceIdle = false;
20628             }
20629             if (!doingAll) {
20630                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20631             } else {
20632                 app.procStateChanged = true;
20633             }
20634         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20635                 > USAGE_STATS_INTERACTION_INTERVAL) {
20636             // For apps that sit around for a long time in the interactive state, we need
20637             // to report this at least once a day so they don't go idle.
20638             maybeUpdateUsageStatsLocked(app, nowElapsed);
20639         }
20640
20641         if (changes != 0) {
20642             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20643                     "Changes in " + app + ": " + changes);
20644             int i = mPendingProcessChanges.size()-1;
20645             ProcessChangeItem item = null;
20646             while (i >= 0) {
20647                 item = mPendingProcessChanges.get(i);
20648                 if (item.pid == app.pid) {
20649                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20650                             "Re-using existing item: " + item);
20651                     break;
20652                 }
20653                 i--;
20654             }
20655             if (i < 0) {
20656                 // No existing item in pending changes; need a new one.
20657                 final int NA = mAvailProcessChanges.size();
20658                 if (NA > 0) {
20659                     item = mAvailProcessChanges.remove(NA-1);
20660                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20661                             "Retrieving available item: " + item);
20662                 } else {
20663                     item = new ProcessChangeItem();
20664                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20665                             "Allocating new item: " + item);
20666                 }
20667                 item.changes = 0;
20668                 item.pid = app.pid;
20669                 item.uid = app.info.uid;
20670                 if (mPendingProcessChanges.size() == 0) {
20671                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20672                             "*** Enqueueing dispatch processes changed!");
20673                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20674                 }
20675                 mPendingProcessChanges.add(item);
20676             }
20677             item.changes |= changes;
20678             item.processState = app.repProcState;
20679             item.foregroundActivities = app.repForegroundActivities;
20680             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20681                     "Item " + Integer.toHexString(System.identityHashCode(item))
20682                     + " " + app.toShortString() + ": changes=" + item.changes
20683                     + " procState=" + item.processState
20684                     + " foreground=" + item.foregroundActivities
20685                     + " type=" + app.adjType + " source=" + app.adjSource
20686                     + " target=" + app.adjTarget);
20687         }
20688
20689         return success;
20690     }
20691
20692     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20693         final UidRecord.ChangeItem pendingChange;
20694         if (uidRec == null || uidRec.pendingChange == null) {
20695             if (mPendingUidChanges.size() == 0) {
20696                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20697                         "*** Enqueueing dispatch uid changed!");
20698                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20699             }
20700             final int NA = mAvailUidChanges.size();
20701             if (NA > 0) {
20702                 pendingChange = mAvailUidChanges.remove(NA-1);
20703                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20704                         "Retrieving available item: " + pendingChange);
20705             } else {
20706                 pendingChange = new UidRecord.ChangeItem();
20707                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20708                         "Allocating new item: " + pendingChange);
20709             }
20710             if (uidRec != null) {
20711                 uidRec.pendingChange = pendingChange;
20712                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20713                     // If this uid is going away, and we haven't yet reported it is gone,
20714                     // then do so now.
20715                     change = UidRecord.CHANGE_GONE_IDLE;
20716                 }
20717             } else if (uid < 0) {
20718                 throw new IllegalArgumentException("No UidRecord or uid");
20719             }
20720             pendingChange.uidRecord = uidRec;
20721             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20722             mPendingUidChanges.add(pendingChange);
20723         } else {
20724             pendingChange = uidRec.pendingChange;
20725             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20726                 change = UidRecord.CHANGE_GONE_IDLE;
20727             }
20728         }
20729         pendingChange.change = change;
20730         pendingChange.processState = uidRec != null
20731                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20732     }
20733
20734     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20735             String authority) {
20736         if (app == null) return;
20737         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20738             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20739             if (userState == null) return;
20740             final long now = SystemClock.elapsedRealtime();
20741             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20742             if (lastReported == null || lastReported < now - 60 * 1000L) {
20743                 if (mSystemReady) {
20744                     // Cannot touch the user stats if not system ready
20745                     mUsageStatsService.reportContentProviderUsage(
20746                             authority, providerPkgName, app.userId);
20747                 }
20748                 userState.mProviderLastReportedFg.put(authority, now);
20749             }
20750         }
20751     }
20752
20753     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20754         if (DEBUG_USAGE_STATS) {
20755             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20756                     + "] state changes: old = " + app.setProcState + ", new = "
20757                     + app.curProcState);
20758         }
20759         if (mUsageStatsService == null) {
20760             return;
20761         }
20762         boolean isInteraction;
20763         // To avoid some abuse patterns, we are going to be careful about what we consider
20764         // to be an app interaction.  Being the top activity doesn't count while the display
20765         // is sleeping, nor do short foreground services.
20766         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20767             isInteraction = true;
20768             app.fgInteractionTime = 0;
20769         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20770             if (app.fgInteractionTime == 0) {
20771                 app.fgInteractionTime = nowElapsed;
20772                 isInteraction = false;
20773             } else {
20774                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20775             }
20776         } else {
20777             // If the app was being forced to the foreground, by say a Toast, then
20778             // no need to treat it as an interaction
20779             isInteraction = app.forcingToForeground == null
20780                     && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20781             app.fgInteractionTime = 0;
20782         }
20783         if (isInteraction && (!app.reportedInteraction
20784                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20785             app.interactionEventTime = nowElapsed;
20786             String[] packages = app.getPackageList();
20787             if (packages != null) {
20788                 for (int i = 0; i < packages.length; i++) {
20789                     mUsageStatsService.reportEvent(packages[i], app.userId,
20790                             UsageEvents.Event.SYSTEM_INTERACTION);
20791                 }
20792             }
20793         }
20794         app.reportedInteraction = isInteraction;
20795         if (!isInteraction) {
20796             app.interactionEventTime = 0;
20797         }
20798     }
20799
20800     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20801         if (proc.thread != null) {
20802             if (proc.baseProcessTracker != null) {
20803                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20804             }
20805         }
20806     }
20807
20808     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20809             ProcessRecord TOP_APP, boolean doingAll, long now) {
20810         if (app.thread == null) {
20811             return false;
20812         }
20813
20814         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20815
20816         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20817     }
20818
20819     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20820             boolean oomAdj) {
20821         if (isForeground != proc.foregroundServices) {
20822             proc.foregroundServices = isForeground;
20823             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20824                     proc.info.uid);
20825             if (isForeground) {
20826                 if (curProcs == null) {
20827                     curProcs = new ArrayList<ProcessRecord>();
20828                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20829                 }
20830                 if (!curProcs.contains(proc)) {
20831                     curProcs.add(proc);
20832                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20833                             proc.info.packageName, proc.info.uid);
20834                 }
20835             } else {
20836                 if (curProcs != null) {
20837                     if (curProcs.remove(proc)) {
20838                         mBatteryStatsService.noteEvent(
20839                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20840                                 proc.info.packageName, proc.info.uid);
20841                         if (curProcs.size() <= 0) {
20842                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20843                         }
20844                     }
20845                 }
20846             }
20847             if (oomAdj) {
20848                 updateOomAdjLocked();
20849             }
20850         }
20851     }
20852
20853     private final ActivityRecord resumedAppLocked() {
20854         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20855         String pkg;
20856         int uid;
20857         if (act != null) {
20858             pkg = act.packageName;
20859             uid = act.info.applicationInfo.uid;
20860         } else {
20861             pkg = null;
20862             uid = -1;
20863         }
20864         // Has the UID or resumed package name changed?
20865         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20866                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20867             if (mCurResumedPackage != null) {
20868                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20869                         mCurResumedPackage, mCurResumedUid);
20870             }
20871             mCurResumedPackage = pkg;
20872             mCurResumedUid = uid;
20873             if (mCurResumedPackage != null) {
20874                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20875                         mCurResumedPackage, mCurResumedUid);
20876             }
20877         }
20878         return act;
20879     }
20880
20881     final boolean updateOomAdjLocked(ProcessRecord app) {
20882         final ActivityRecord TOP_ACT = resumedAppLocked();
20883         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20884         final boolean wasCached = app.cached;
20885
20886         mAdjSeq++;
20887
20888         // This is the desired cached adjusment we want to tell it to use.
20889         // If our app is currently cached, we know it, and that is it.  Otherwise,
20890         // we don't know it yet, and it needs to now be cached we will then
20891         // need to do a complete oom adj.
20892         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20893                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20894         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20895                 SystemClock.uptimeMillis());
20896         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20897             // Changed to/from cached state, so apps after it in the LRU
20898             // list may also be changed.
20899             updateOomAdjLocked();
20900         }
20901         return success;
20902     }
20903
20904     final void updateOomAdjLocked() {
20905         final ActivityRecord TOP_ACT = resumedAppLocked();
20906         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20907         final long now = SystemClock.uptimeMillis();
20908         final long nowElapsed = SystemClock.elapsedRealtime();
20909         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20910         final int N = mLruProcesses.size();
20911
20912         if (false) {
20913             RuntimeException e = new RuntimeException();
20914             e.fillInStackTrace();
20915             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20916         }
20917
20918         // Reset state in all uid records.
20919         for (int i=mActiveUids.size()-1; i>=0; i--) {
20920             final UidRecord uidRec = mActiveUids.valueAt(i);
20921             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20922                     "Starting update of " + uidRec);
20923             uidRec.reset();
20924         }
20925
20926         mStackSupervisor.rankTaskLayersIfNeeded();
20927
20928         mAdjSeq++;
20929         mNewNumServiceProcs = 0;
20930         mNewNumAServiceProcs = 0;
20931
20932         final int emptyProcessLimit;
20933         final int cachedProcessLimit;
20934         if (mProcessLimit <= 0) {
20935             emptyProcessLimit = cachedProcessLimit = 0;
20936         } else if (mProcessLimit == 1) {
20937             emptyProcessLimit = 1;
20938             cachedProcessLimit = 0;
20939         } else {
20940             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20941             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20942         }
20943
20944         // Let's determine how many processes we have running vs.
20945         // how many slots we have for background processes; we may want
20946         // to put multiple processes in a slot of there are enough of
20947         // them.
20948         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20949                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20950         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20951         if (numEmptyProcs > cachedProcessLimit) {
20952             // If there are more empty processes than our limit on cached
20953             // processes, then use the cached process limit for the factor.
20954             // This ensures that the really old empty processes get pushed
20955             // down to the bottom, so if we are running low on memory we will
20956             // have a better chance at keeping around more cached processes
20957             // instead of a gazillion empty processes.
20958             numEmptyProcs = cachedProcessLimit;
20959         }
20960         int emptyFactor = numEmptyProcs/numSlots;
20961         if (emptyFactor < 1) emptyFactor = 1;
20962         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20963         if (cachedFactor < 1) cachedFactor = 1;
20964         int stepCached = 0;
20965         int stepEmpty = 0;
20966         int numCached = 0;
20967         int numEmpty = 0;
20968         int numTrimming = 0;
20969
20970         mNumNonCachedProcs = 0;
20971         mNumCachedHiddenProcs = 0;
20972
20973         // First update the OOM adjustment for each of the
20974         // application processes based on their current state.
20975         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20976         int nextCachedAdj = curCachedAdj+1;
20977         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20978         int nextEmptyAdj = curEmptyAdj+2;
20979         for (int i=N-1; i>=0; i--) {
20980             ProcessRecord app = mLruProcesses.get(i);
20981             if (!app.killedByAm && app.thread != null) {
20982                 app.procStateChanged = false;
20983                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20984
20985                 // If we haven't yet assigned the final cached adj
20986                 // to the process, do that now.
20987                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20988                     switch (app.curProcState) {
20989                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20990                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20991                             // This process is a cached process holding activities...
20992                             // assign it the next cached value for that type, and then
20993                             // step that cached level.
20994                             app.curRawAdj = curCachedAdj;
20995                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20996                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20997                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20998                                     + ")");
20999                             if (curCachedAdj != nextCachedAdj) {
21000                                 stepCached++;
21001                                 if (stepCached >= cachedFactor) {
21002                                     stepCached = 0;
21003                                     curCachedAdj = nextCachedAdj;
21004                                     nextCachedAdj += 2;
21005                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21006                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21007                                     }
21008                                 }
21009                             }
21010                             break;
21011                         default:
21012                             // For everything else, assign next empty cached process
21013                             // level and bump that up.  Note that this means that
21014                             // long-running services that have dropped down to the
21015                             // cached level will be treated as empty (since their process
21016                             // state is still as a service), which is what we want.
21017                             app.curRawAdj = curEmptyAdj;
21018                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21019                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21020                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21021                                     + ")");
21022                             if (curEmptyAdj != nextEmptyAdj) {
21023                                 stepEmpty++;
21024                                 if (stepEmpty >= emptyFactor) {
21025                                     stepEmpty = 0;
21026                                     curEmptyAdj = nextEmptyAdj;
21027                                     nextEmptyAdj += 2;
21028                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21029                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21030                                     }
21031                                 }
21032                             }
21033                             break;
21034                     }
21035                 }
21036
21037                 applyOomAdjLocked(app, true, now, nowElapsed);
21038
21039                 // Count the number of process types.
21040                 switch (app.curProcState) {
21041                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21042                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21043                         mNumCachedHiddenProcs++;
21044                         numCached++;
21045                         if (numCached > cachedProcessLimit) {
21046                             app.kill("cached #" + numCached, true);
21047                         }
21048                         break;
21049                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21050                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21051                                 && app.lastActivityTime < oldTime) {
21052                             app.kill("empty for "
21053                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21054                                     / 1000) + "s", true);
21055                         } else {
21056                             numEmpty++;
21057                             if (numEmpty > emptyProcessLimit) {
21058                                 app.kill("empty #" + numEmpty, true);
21059                             }
21060                         }
21061                         break;
21062                     default:
21063                         mNumNonCachedProcs++;
21064                         break;
21065                 }
21066
21067                 if (app.isolated && app.services.size() <= 0) {
21068                     // If this is an isolated process, and there are no
21069                     // services running in it, then the process is no longer
21070                     // needed.  We agressively kill these because we can by
21071                     // definition not re-use the same process again, and it is
21072                     // good to avoid having whatever code was running in them
21073                     // left sitting around after no longer needed.
21074                     app.kill("isolated not needed", true);
21075                 } else {
21076                     // Keeping this process, update its uid.
21077                     final UidRecord uidRec = app.uidRecord;
21078                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
21079                         uidRec.curProcState = app.curProcState;
21080                     }
21081                 }
21082
21083                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21084                         && !app.killedByAm) {
21085                     numTrimming++;
21086                 }
21087             }
21088         }
21089
21090         mNumServiceProcs = mNewNumServiceProcs;
21091
21092         // Now determine the memory trimming level of background processes.
21093         // Unfortunately we need to start at the back of the list to do this
21094         // properly.  We only do this if the number of background apps we
21095         // are managing to keep around is less than half the maximum we desire;
21096         // if we are keeping a good number around, we'll let them use whatever
21097         // memory they want.
21098         final int numCachedAndEmpty = numCached + numEmpty;
21099         int memFactor;
21100         if (numCached <= ProcessList.TRIM_CACHED_APPS
21101                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21102             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21103                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21104             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21105                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21106             } else {
21107                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21108             }
21109         } else {
21110             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21111         }
21112         // We always allow the memory level to go up (better).  We only allow it to go
21113         // down if we are in a state where that is allowed, *and* the total number of processes
21114         // has gone down since last time.
21115         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21116                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21117                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21118         if (memFactor > mLastMemoryLevel) {
21119             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21120                 memFactor = mLastMemoryLevel;
21121                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21122             }
21123         }
21124         if (memFactor != mLastMemoryLevel) {
21125             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21126         }
21127         mLastMemoryLevel = memFactor;
21128         mLastNumProcesses = mLruProcesses.size();
21129         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21130         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21131         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21132             if (mLowRamStartTime == 0) {
21133                 mLowRamStartTime = now;
21134             }
21135             int step = 0;
21136             int fgTrimLevel;
21137             switch (memFactor) {
21138                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21139                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21140                     break;
21141                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21142                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21143                     break;
21144                 default:
21145                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21146                     break;
21147             }
21148             int factor = numTrimming/3;
21149             int minFactor = 2;
21150             if (mHomeProcess != null) minFactor++;
21151             if (mPreviousProcess != null) minFactor++;
21152             if (factor < minFactor) factor = minFactor;
21153             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21154             for (int i=N-1; i>=0; i--) {
21155                 ProcessRecord app = mLruProcesses.get(i);
21156                 if (allChanged || app.procStateChanged) {
21157                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21158                     app.procStateChanged = false;
21159                 }
21160                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21161                         && !app.killedByAm) {
21162                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21163                         try {
21164                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21165                                     "Trimming memory of " + app.processName + " to " + curLevel);
21166                             app.thread.scheduleTrimMemory(curLevel);
21167                         } catch (RemoteException e) {
21168                         }
21169                         if (false) {
21170                             // For now we won't do this; our memory trimming seems
21171                             // to be good enough at this point that destroying
21172                             // activities causes more harm than good.
21173                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21174                                     && app != mHomeProcess && app != mPreviousProcess) {
21175                                 // Need to do this on its own message because the stack may not
21176                                 // be in a consistent state at this point.
21177                                 // For these apps we will also finish their activities
21178                                 // to help them free memory.
21179                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21180                             }
21181                         }
21182                     }
21183                     app.trimMemoryLevel = curLevel;
21184                     step++;
21185                     if (step >= factor) {
21186                         step = 0;
21187                         switch (curLevel) {
21188                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21189                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21190                                 break;
21191                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21192                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21193                                 break;
21194                         }
21195                     }
21196                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21197                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21198                             && app.thread != null) {
21199                         try {
21200                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21201                                     "Trimming memory of heavy-weight " + app.processName
21202                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21203                             app.thread.scheduleTrimMemory(
21204                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21205                         } catch (RemoteException e) {
21206                         }
21207                     }
21208                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21209                 } else {
21210                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21211                             || app.systemNoUi) && app.pendingUiClean) {
21212                         // If this application is now in the background and it
21213                         // had done UI, then give it the special trim level to
21214                         // have it free UI resources.
21215                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21216                         if (app.trimMemoryLevel < level && app.thread != null) {
21217                             try {
21218                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21219                                         "Trimming memory of bg-ui " + app.processName
21220                                         + " to " + level);
21221                                 app.thread.scheduleTrimMemory(level);
21222                             } catch (RemoteException e) {
21223                             }
21224                         }
21225                         app.pendingUiClean = false;
21226                     }
21227                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21228                         try {
21229                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21230                                     "Trimming memory of fg " + app.processName
21231                                     + " to " + fgTrimLevel);
21232                             app.thread.scheduleTrimMemory(fgTrimLevel);
21233                         } catch (RemoteException e) {
21234                         }
21235                     }
21236                     app.trimMemoryLevel = fgTrimLevel;
21237                 }
21238             }
21239         } else {
21240             if (mLowRamStartTime != 0) {
21241                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21242                 mLowRamStartTime = 0;
21243             }
21244             for (int i=N-1; i>=0; i--) {
21245                 ProcessRecord app = mLruProcesses.get(i);
21246                 if (allChanged || app.procStateChanged) {
21247                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21248                     app.procStateChanged = false;
21249                 }
21250                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21251                         || app.systemNoUi) && app.pendingUiClean) {
21252                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21253                             && app.thread != null) {
21254                         try {
21255                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21256                                     "Trimming memory of ui hidden " + app.processName
21257                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21258                             app.thread.scheduleTrimMemory(
21259                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21260                         } catch (RemoteException e) {
21261                         }
21262                     }
21263                     app.pendingUiClean = false;
21264                 }
21265                 app.trimMemoryLevel = 0;
21266             }
21267         }
21268
21269         if (mAlwaysFinishActivities) {
21270             // Need to do this on its own message because the stack may not
21271             // be in a consistent state at this point.
21272             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21273         }
21274
21275         if (allChanged) {
21276             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21277         }
21278
21279         // Update from any uid changes.
21280         for (int i=mActiveUids.size()-1; i>=0; i--) {
21281             final UidRecord uidRec = mActiveUids.valueAt(i);
21282             int uidChange = UidRecord.CHANGE_PROCSTATE;
21283             if (uidRec.setProcState != uidRec.curProcState) {
21284                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21285                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21286                         + " to " + uidRec.curProcState);
21287                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21288                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21289                         uidRec.lastBackgroundTime = nowElapsed;
21290                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21291                             // Note: the background settle time is in elapsed realtime, while
21292                             // the handler time base is uptime.  All this means is that we may
21293                             // stop background uids later than we had intended, but that only
21294                             // happens because the device was sleeping so we are okay anyway.
21295                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21296                         }
21297                     }
21298                 } else {
21299                     if (uidRec.idle) {
21300                         uidChange = UidRecord.CHANGE_ACTIVE;
21301                         uidRec.idle = false;
21302                     }
21303                     uidRec.lastBackgroundTime = 0;
21304                 }
21305                 uidRec.setProcState = uidRec.curProcState;
21306                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21307                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21308             }
21309         }
21310
21311         if (mProcessStats.shouldWriteNowLocked(now)) {
21312             mHandler.post(new Runnable() {
21313                 @Override public void run() {
21314                     synchronized (ActivityManagerService.this) {
21315                         mProcessStats.writeStateAsyncLocked();
21316                     }
21317                 }
21318             });
21319         }
21320
21321         if (DEBUG_OOM_ADJ) {
21322             final long duration = SystemClock.uptimeMillis() - now;
21323             if (false) {
21324                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21325                         new RuntimeException("here").fillInStackTrace());
21326             } else {
21327                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21328             }
21329         }
21330     }
21331
21332     final void idleUids() {
21333         synchronized (this) {
21334             final long nowElapsed = SystemClock.elapsedRealtime();
21335             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21336             long nextTime = 0;
21337             for (int i=mActiveUids.size()-1; i>=0; i--) {
21338                 final UidRecord uidRec = mActiveUids.valueAt(i);
21339                 final long bgTime = uidRec.lastBackgroundTime;
21340                 if (bgTime > 0 && !uidRec.idle) {
21341                     if (bgTime <= maxBgTime) {
21342                         uidRec.idle = true;
21343                         doStopUidLocked(uidRec.uid, uidRec);
21344                     } else {
21345                         if (nextTime == 0 || nextTime > bgTime) {
21346                             nextTime = bgTime;
21347                         }
21348                     }
21349                 }
21350             }
21351             if (nextTime > 0) {
21352                 mHandler.removeMessages(IDLE_UIDS_MSG);
21353                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21354                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21355             }
21356         }
21357     }
21358
21359     final void runInBackgroundDisabled(int uid) {
21360         synchronized (this) {
21361             UidRecord uidRec = mActiveUids.get(uid);
21362             if (uidRec != null) {
21363                 // This uid is actually running...  should it be considered background now?
21364                 if (uidRec.idle) {
21365                     doStopUidLocked(uidRec.uid, uidRec);
21366                 }
21367             } else {
21368                 // This uid isn't actually running...  still send a report about it being "stopped".
21369                 doStopUidLocked(uid, null);
21370             }
21371         }
21372     }
21373
21374     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21375         mServices.stopInBackgroundLocked(uid);
21376         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21377     }
21378
21379     final void trimApplications() {
21380         synchronized (this) {
21381             int i;
21382
21383             // First remove any unused application processes whose package
21384             // has been removed.
21385             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21386                 final ProcessRecord app = mRemovedProcesses.get(i);
21387                 if (app.activities.size() == 0
21388                         && app.curReceiver == null && app.services.size() == 0) {
21389                     Slog.i(
21390                         TAG, "Exiting empty application process "
21391                         + app.toShortString() + " ("
21392                         + (app.thread != null ? app.thread.asBinder() : null)
21393                         + ")\n");
21394                     if (app.pid > 0 && app.pid != MY_PID) {
21395                         app.kill("empty", false);
21396                     } else {
21397                         try {
21398                             app.thread.scheduleExit();
21399                         } catch (Exception e) {
21400                             // Ignore exceptions.
21401                         }
21402                     }
21403                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21404                     mRemovedProcesses.remove(i);
21405
21406                     if (app.persistent) {
21407                         addAppLocked(app.info, false, null /* ABI override */);
21408                     }
21409                 }
21410             }
21411
21412             // Now update the oom adj for all processes.
21413             updateOomAdjLocked();
21414         }
21415     }
21416
21417     /** This method sends the specified signal to each of the persistent apps */
21418     public void signalPersistentProcesses(int sig) throws RemoteException {
21419         if (sig != Process.SIGNAL_USR1) {
21420             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21421         }
21422
21423         synchronized (this) {
21424             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21425                     != PackageManager.PERMISSION_GRANTED) {
21426                 throw new SecurityException("Requires permission "
21427                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21428             }
21429
21430             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21431                 ProcessRecord r = mLruProcesses.get(i);
21432                 if (r.thread != null && r.persistent) {
21433                     Process.sendSignal(r.pid, sig);
21434                 }
21435             }
21436         }
21437     }
21438
21439     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21440         if (proc == null || proc == mProfileProc) {
21441             proc = mProfileProc;
21442             profileType = mProfileType;
21443             clearProfilerLocked();
21444         }
21445         if (proc == null) {
21446             return;
21447         }
21448         try {
21449             proc.thread.profilerControl(false, null, profileType);
21450         } catch (RemoteException e) {
21451             throw new IllegalStateException("Process disappeared");
21452         }
21453     }
21454
21455     private void clearProfilerLocked() {
21456         if (mProfileFd != null) {
21457             try {
21458                 mProfileFd.close();
21459             } catch (IOException e) {
21460             }
21461         }
21462         mProfileApp = null;
21463         mProfileProc = null;
21464         mProfileFile = null;
21465         mProfileType = 0;
21466         mAutoStopProfiler = false;
21467         mSamplingInterval = 0;
21468     }
21469
21470     public boolean profileControl(String process, int userId, boolean start,
21471             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21472
21473         try {
21474             synchronized (this) {
21475                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21476                 // its own permission.
21477                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21478                         != PackageManager.PERMISSION_GRANTED) {
21479                     throw new SecurityException("Requires permission "
21480                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21481                 }
21482
21483                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21484                     throw new IllegalArgumentException("null profile info or fd");
21485                 }
21486
21487                 ProcessRecord proc = null;
21488                 if (process != null) {
21489                     proc = findProcessLocked(process, userId, "profileControl");
21490                 }
21491
21492                 if (start && (proc == null || proc.thread == null)) {
21493                     throw new IllegalArgumentException("Unknown process: " + process);
21494                 }
21495
21496                 if (start) {
21497                     stopProfilerLocked(null, 0);
21498                     setProfileApp(proc.info, proc.processName, profilerInfo);
21499                     mProfileProc = proc;
21500                     mProfileType = profileType;
21501                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21502                     try {
21503                         fd = fd.dup();
21504                     } catch (IOException e) {
21505                         fd = null;
21506                     }
21507                     profilerInfo.profileFd = fd;
21508                     proc.thread.profilerControl(start, profilerInfo, profileType);
21509                     fd = null;
21510                     mProfileFd = null;
21511                 } else {
21512                     stopProfilerLocked(proc, profileType);
21513                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21514                         try {
21515                             profilerInfo.profileFd.close();
21516                         } catch (IOException e) {
21517                         }
21518                     }
21519                 }
21520
21521                 return true;
21522             }
21523         } catch (RemoteException e) {
21524             throw new IllegalStateException("Process disappeared");
21525         } finally {
21526             if (profilerInfo != null && profilerInfo.profileFd != null) {
21527                 try {
21528                     profilerInfo.profileFd.close();
21529                 } catch (IOException e) {
21530                 }
21531             }
21532         }
21533     }
21534
21535     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21536         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21537                 userId, true, ALLOW_FULL_ONLY, callName, null);
21538         ProcessRecord proc = null;
21539         try {
21540             int pid = Integer.parseInt(process);
21541             synchronized (mPidsSelfLocked) {
21542                 proc = mPidsSelfLocked.get(pid);
21543             }
21544         } catch (NumberFormatException e) {
21545         }
21546
21547         if (proc == null) {
21548             ArrayMap<String, SparseArray<ProcessRecord>> all
21549                     = mProcessNames.getMap();
21550             SparseArray<ProcessRecord> procs = all.get(process);
21551             if (procs != null && procs.size() > 0) {
21552                 proc = procs.valueAt(0);
21553                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21554                     for (int i=1; i<procs.size(); i++) {
21555                         ProcessRecord thisProc = procs.valueAt(i);
21556                         if (thisProc.userId == userId) {
21557                             proc = thisProc;
21558                             break;
21559                         }
21560                     }
21561                 }
21562             }
21563         }
21564
21565         return proc;
21566     }
21567
21568     public boolean dumpHeap(String process, int userId, boolean managed,
21569             String path, ParcelFileDescriptor fd) throws RemoteException {
21570
21571         try {
21572             synchronized (this) {
21573                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21574                 // its own permission (same as profileControl).
21575                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21576                         != PackageManager.PERMISSION_GRANTED) {
21577                     throw new SecurityException("Requires permission "
21578                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21579                 }
21580
21581                 if (fd == null) {
21582                     throw new IllegalArgumentException("null fd");
21583                 }
21584
21585                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21586                 if (proc == null || proc.thread == null) {
21587                     throw new IllegalArgumentException("Unknown process: " + process);
21588                 }
21589
21590                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21591                 if (!isDebuggable) {
21592                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21593                         throw new SecurityException("Process not debuggable: " + proc);
21594                     }
21595                 }
21596
21597                 proc.thread.dumpHeap(managed, path, fd);
21598                 fd = null;
21599                 return true;
21600             }
21601         } catch (RemoteException e) {
21602             throw new IllegalStateException("Process disappeared");
21603         } finally {
21604             if (fd != null) {
21605                 try {
21606                     fd.close();
21607                 } catch (IOException e) {
21608                 }
21609             }
21610         }
21611     }
21612
21613     @Override
21614     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21615             String reportPackage) {
21616         if (processName != null) {
21617             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21618                     "setDumpHeapDebugLimit()");
21619         } else {
21620             synchronized (mPidsSelfLocked) {
21621                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21622                 if (proc == null) {
21623                     throw new SecurityException("No process found for calling pid "
21624                             + Binder.getCallingPid());
21625                 }
21626                 if (!Build.IS_DEBUGGABLE
21627                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21628                     throw new SecurityException("Not running a debuggable build");
21629                 }
21630                 processName = proc.processName;
21631                 uid = proc.uid;
21632                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21633                     throw new SecurityException("Package " + reportPackage + " is not running in "
21634                             + proc);
21635                 }
21636             }
21637         }
21638         synchronized (this) {
21639             if (maxMemSize > 0) {
21640                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21641             } else {
21642                 if (uid != 0) {
21643                     mMemWatchProcesses.remove(processName, uid);
21644                 } else {
21645                     mMemWatchProcesses.getMap().remove(processName);
21646                 }
21647             }
21648         }
21649     }
21650
21651     @Override
21652     public void dumpHeapFinished(String path) {
21653         synchronized (this) {
21654             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21655                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21656                         + " does not match last pid " + mMemWatchDumpPid);
21657                 return;
21658             }
21659             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21660                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21661                         + " does not match last path " + mMemWatchDumpFile);
21662                 return;
21663             }
21664             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21665             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21666         }
21667     }
21668
21669     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21670     public void monitor() {
21671         synchronized (this) { }
21672     }
21673
21674     void onCoreSettingsChange(Bundle settings) {
21675         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21676             ProcessRecord processRecord = mLruProcesses.get(i);
21677             try {
21678                 if (processRecord.thread != null) {
21679                     processRecord.thread.setCoreSettings(settings);
21680                 }
21681             } catch (RemoteException re) {
21682                 /* ignore */
21683             }
21684         }
21685     }
21686
21687     // Multi-user methods
21688
21689     /**
21690      * Start user, if its not already running, but don't bring it to foreground.
21691      */
21692     @Override
21693     public boolean startUserInBackground(final int userId) {
21694         return mUserController.startUser(userId, /* foreground */ false);
21695     }
21696
21697     @Override
21698     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21699         return mUserController.unlockUser(userId, token, secret, listener);
21700     }
21701
21702     @Override
21703     public boolean switchUser(final int targetUserId) {
21704         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21705         UserInfo currentUserInfo;
21706         UserInfo targetUserInfo;
21707         synchronized (this) {
21708             int currentUserId = mUserController.getCurrentUserIdLocked();
21709             currentUserInfo = mUserController.getUserInfo(currentUserId);
21710             targetUserInfo = mUserController.getUserInfo(targetUserId);
21711             if (targetUserInfo == null) {
21712                 Slog.w(TAG, "No user info for user #" + targetUserId);
21713                 return false;
21714             }
21715             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21716                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21717                         + " when device is in demo mode");
21718                 return false;
21719             }
21720             if (!targetUserInfo.supportsSwitchTo()) {
21721                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21722                 return false;
21723             }
21724             if (targetUserInfo.isManagedProfile()) {
21725                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21726                 return false;
21727             }
21728             mUserController.setTargetUserIdLocked(targetUserId);
21729         }
21730         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21731         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21732         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21733         return true;
21734     }
21735
21736     void scheduleStartProfilesLocked() {
21737         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21738             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21739                     DateUtils.SECOND_IN_MILLIS);
21740         }
21741     }
21742
21743     @Override
21744     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21745         return mUserController.stopUser(userId, force, callback);
21746     }
21747
21748     @Override
21749     public UserInfo getCurrentUser() {
21750         return mUserController.getCurrentUser();
21751     }
21752
21753     @Override
21754     public boolean isUserRunning(int userId, int flags) {
21755         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21756                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21757                     != PackageManager.PERMISSION_GRANTED) {
21758             String msg = "Permission Denial: isUserRunning() from pid="
21759                     + Binder.getCallingPid()
21760                     + ", uid=" + Binder.getCallingUid()
21761                     + " requires " + INTERACT_ACROSS_USERS;
21762             Slog.w(TAG, msg);
21763             throw new SecurityException(msg);
21764         }
21765         synchronized (this) {
21766             return mUserController.isUserRunningLocked(userId, flags);
21767         }
21768     }
21769
21770     @Override
21771     public int[] getRunningUserIds() {
21772         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21773                 != PackageManager.PERMISSION_GRANTED) {
21774             String msg = "Permission Denial: isUserRunning() from pid="
21775                     + Binder.getCallingPid()
21776                     + ", uid=" + Binder.getCallingUid()
21777                     + " requires " + INTERACT_ACROSS_USERS;
21778             Slog.w(TAG, msg);
21779             throw new SecurityException(msg);
21780         }
21781         synchronized (this) {
21782             return mUserController.getStartedUserArrayLocked();
21783         }
21784     }
21785
21786     @Override
21787     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21788         mUserController.registerUserSwitchObserver(observer, name);
21789     }
21790
21791     @Override
21792     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21793         mUserController.unregisterUserSwitchObserver(observer);
21794     }
21795
21796     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21797         if (info == null) return null;
21798         ApplicationInfo newInfo = new ApplicationInfo(info);
21799         newInfo.initForUser(userId);
21800         return newInfo;
21801     }
21802
21803     public boolean isUserStopped(int userId) {
21804         synchronized (this) {
21805             return mUserController.getStartedUserStateLocked(userId) == null;
21806         }
21807     }
21808
21809     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21810         if (aInfo == null
21811                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21812             return aInfo;
21813         }
21814
21815         ActivityInfo info = new ActivityInfo(aInfo);
21816         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21817         return info;
21818     }
21819
21820     private boolean processSanityChecksLocked(ProcessRecord process) {
21821         if (process == null || process.thread == null) {
21822             return false;
21823         }
21824
21825         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21826         if (!isDebuggable) {
21827             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21828                 return false;
21829             }
21830         }
21831
21832         return true;
21833     }
21834
21835     public boolean startBinderTracking() throws RemoteException {
21836         synchronized (this) {
21837             mBinderTransactionTrackingEnabled = true;
21838             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21839             // permission (same as profileControl).
21840             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21841                     != PackageManager.PERMISSION_GRANTED) {
21842                 throw new SecurityException("Requires permission "
21843                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21844             }
21845
21846             for (int i = 0; i < mLruProcesses.size(); i++) {
21847                 ProcessRecord process = mLruProcesses.get(i);
21848                 if (!processSanityChecksLocked(process)) {
21849                     continue;
21850                 }
21851                 try {
21852                     process.thread.startBinderTracking();
21853                 } catch (RemoteException e) {
21854                     Log.v(TAG, "Process disappared");
21855                 }
21856             }
21857             return true;
21858         }
21859     }
21860
21861     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21862         try {
21863             synchronized (this) {
21864                 mBinderTransactionTrackingEnabled = false;
21865                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21866                 // permission (same as profileControl).
21867                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21868                         != PackageManager.PERMISSION_GRANTED) {
21869                     throw new SecurityException("Requires permission "
21870                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21871                 }
21872
21873                 if (fd == null) {
21874                     throw new IllegalArgumentException("null fd");
21875                 }
21876
21877                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21878                 pw.println("Binder transaction traces for all processes.\n");
21879                 for (ProcessRecord process : mLruProcesses) {
21880                     if (!processSanityChecksLocked(process)) {
21881                         continue;
21882                     }
21883
21884                     pw.println("Traces for process: " + process.processName);
21885                     pw.flush();
21886                     try {
21887                         TransferPipe tp = new TransferPipe();
21888                         try {
21889                             process.thread.stopBinderTrackingAndDump(
21890                                     tp.getWriteFd().getFileDescriptor());
21891                             tp.go(fd.getFileDescriptor());
21892                         } finally {
21893                             tp.kill();
21894                         }
21895                     } catch (IOException e) {
21896                         pw.println("Failure while dumping IPC traces from " + process +
21897                                 ".  Exception: " + e);
21898                         pw.flush();
21899                     } catch (RemoteException e) {
21900                         pw.println("Got a RemoteException while dumping IPC traces from " +
21901                                 process + ".  Exception: " + e);
21902                         pw.flush();
21903                     }
21904                 }
21905                 fd = null;
21906                 return true;
21907             }
21908         } finally {
21909             if (fd != null) {
21910                 try {
21911                     fd.close();
21912                 } catch (IOException e) {
21913                 }
21914             }
21915         }
21916     }
21917
21918     private final class LocalService extends ActivityManagerInternal {
21919         @Override
21920         public String checkContentProviderAccess(String authority, int userId) {
21921             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21922         }
21923
21924         @Override
21925         public void onWakefulnessChanged(int wakefulness) {
21926             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21927         }
21928
21929         @Override
21930         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21931                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21932             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21933                     processName, abiOverride, uid, crashHandler);
21934         }
21935
21936         @Override
21937         public SleepToken acquireSleepToken(String tag) {
21938             Preconditions.checkNotNull(tag);
21939
21940             ComponentName requestedVrService = null;
21941             ComponentName callingVrActivity = null;
21942             int userId = -1;
21943             synchronized (ActivityManagerService.this) {
21944                 if (mFocusedActivity != null) {
21945                     requestedVrService = mFocusedActivity.requestedVrComponent;
21946                     callingVrActivity = mFocusedActivity.info.getComponentName();
21947                     userId = mFocusedActivity.userId;
21948                 }
21949             }
21950
21951             if (requestedVrService != null) {
21952                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21953             }
21954
21955             synchronized (ActivityManagerService.this) {
21956                 SleepTokenImpl token = new SleepTokenImpl(tag);
21957                 mSleepTokens.add(token);
21958                 updateSleepIfNeededLocked();
21959                 return token;
21960             }
21961         }
21962
21963         @Override
21964         public ComponentName getHomeActivityForUser(int userId) {
21965             synchronized (ActivityManagerService.this) {
21966                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21967                 return homeActivity == null ? null : homeActivity.realActivity;
21968             }
21969         }
21970
21971         @Override
21972         public void onUserRemoved(int userId) {
21973             synchronized (ActivityManagerService.this) {
21974                 ActivityManagerService.this.onUserStoppedLocked(userId);
21975             }
21976         }
21977
21978         @Override
21979         public void onLocalVoiceInteractionStarted(IBinder activity,
21980                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21981             synchronized (ActivityManagerService.this) {
21982                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21983                         voiceSession, voiceInteractor);
21984             }
21985         }
21986
21987         @Override
21988         public void notifyStartingWindowDrawn() {
21989             synchronized (ActivityManagerService.this) {
21990                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21991             }
21992         }
21993
21994         @Override
21995         public void notifyAppTransitionStarting(int reason) {
21996             synchronized (ActivityManagerService.this) {
21997                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21998             }
21999         }
22000
22001         @Override
22002         public void notifyAppTransitionFinished() {
22003             synchronized (ActivityManagerService.this) {
22004                 mStackSupervisor.notifyAppTransitionDone();
22005             }
22006         }
22007
22008         @Override
22009         public void notifyAppTransitionCancelled() {
22010             synchronized (ActivityManagerService.this) {
22011                 mStackSupervisor.notifyAppTransitionDone();
22012             }
22013         }
22014
22015         @Override
22016         public List<IBinder> getTopVisibleActivities() {
22017             synchronized (ActivityManagerService.this) {
22018                 return mStackSupervisor.getTopVisibleActivities();
22019             }
22020         }
22021
22022         @Override
22023         public void notifyDockedStackMinimizedChanged(boolean minimized) {
22024             synchronized (ActivityManagerService.this) {
22025                 mStackSupervisor.setDockedStackMinimized(minimized);
22026             }
22027         }
22028
22029         @Override
22030         public void killForegroundAppsForUser(int userHandle) {
22031             synchronized (ActivityManagerService.this) {
22032                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22033                 final int NP = mProcessNames.getMap().size();
22034                 for (int ip = 0; ip < NP; ip++) {
22035                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22036                     final int NA = apps.size();
22037                     for (int ia = 0; ia < NA; ia++) {
22038                         final ProcessRecord app = apps.valueAt(ia);
22039                         if (app.persistent) {
22040                             // We don't kill persistent processes.
22041                             continue;
22042                         }
22043                         if (app.removed) {
22044                             procs.add(app);
22045                         } else if (app.userId == userHandle && app.foregroundActivities) {
22046                             app.removed = true;
22047                             procs.add(app);
22048                         }
22049                     }
22050                 }
22051
22052                 final int N = procs.size();
22053                 for (int i = 0; i < N; i++) {
22054                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
22055                 }
22056             }
22057         }
22058
22059         @Override
22060         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22061             if (!(target instanceof PendingIntentRecord)) {
22062                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22063                 return;
22064             }
22065             ((PendingIntentRecord) target).setWhitelistDuration(duration);
22066         }
22067
22068         @Override
22069         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22070                 int userId) {
22071             Preconditions.checkNotNull(values, "Configuration must not be null");
22072             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22073             synchronized (ActivityManagerService.this) {
22074                 updateConfigurationLocked(values, null, false, true, userId,
22075                         false /* deferResume */);
22076             }
22077         }
22078
22079         @Override
22080         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22081                 Bundle bOptions) {
22082             Preconditions.checkNotNull(intents, "intents");
22083             final String[] resolvedTypes = new String[intents.length];
22084             for (int i = 0; i < intents.length; i++) {
22085                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22086             }
22087
22088             // UID of the package on user userId.
22089             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22090             // packageUid may not be initialized.
22091             int packageUid = 0;
22092             try {
22093                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22094                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22095             } catch (RemoteException e) {
22096                 // Shouldn't happen.
22097             }
22098
22099             synchronized (ActivityManagerService.this) {
22100                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22101                         /*resultTo*/ null, bOptions, userId);
22102             }
22103         }
22104
22105         @Override
22106         public int getUidProcessState(int uid) {
22107             return getUidState(uid);
22108         }
22109     }
22110
22111     private final class SleepTokenImpl extends SleepToken {
22112         private final String mTag;
22113         private final long mAcquireTime;
22114
22115         public SleepTokenImpl(String tag) {
22116             mTag = tag;
22117             mAcquireTime = SystemClock.uptimeMillis();
22118         }
22119
22120         @Override
22121         public void release() {
22122             synchronized (ActivityManagerService.this) {
22123                 if (mSleepTokens.remove(this)) {
22124                     updateSleepIfNeededLocked();
22125                 }
22126             }
22127         }
22128
22129         @Override
22130         public String toString() {
22131             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22132         }
22133     }
22134
22135     /**
22136      * An implementation of IAppTask, that allows an app to manage its own tasks via
22137      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22138      * only the process that calls getAppTasks() can call the AppTask methods.
22139      */
22140     class AppTaskImpl extends IAppTask.Stub {
22141         private int mTaskId;
22142         private int mCallingUid;
22143
22144         public AppTaskImpl(int taskId, int callingUid) {
22145             mTaskId = taskId;
22146             mCallingUid = callingUid;
22147         }
22148
22149         private void checkCaller() {
22150             if (mCallingUid != Binder.getCallingUid()) {
22151                 throw new SecurityException("Caller " + mCallingUid
22152                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22153             }
22154         }
22155
22156         @Override
22157         public void finishAndRemoveTask() {
22158             checkCaller();
22159
22160             synchronized (ActivityManagerService.this) {
22161                 long origId = Binder.clearCallingIdentity();
22162                 try {
22163                     // We remove the task from recents to preserve backwards
22164                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22165                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22166                     }
22167                 } finally {
22168                     Binder.restoreCallingIdentity(origId);
22169                 }
22170             }
22171         }
22172
22173         @Override
22174         public ActivityManager.RecentTaskInfo getTaskInfo() {
22175             checkCaller();
22176
22177             synchronized (ActivityManagerService.this) {
22178                 long origId = Binder.clearCallingIdentity();
22179                 try {
22180                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22181                     if (tr == null) {
22182                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22183                     }
22184                     return createRecentTaskInfoFromTaskRecord(tr);
22185                 } finally {
22186                     Binder.restoreCallingIdentity(origId);
22187                 }
22188             }
22189         }
22190
22191         @Override
22192         public void moveToFront() {
22193             checkCaller();
22194             // Will bring task to front if it already has a root activity.
22195             final long origId = Binder.clearCallingIdentity();
22196             try {
22197                 synchronized (this) {
22198                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22199                 }
22200             } finally {
22201                 Binder.restoreCallingIdentity(origId);
22202             }
22203         }
22204
22205         @Override
22206         public int startActivity(IBinder whoThread, String callingPackage,
22207                 Intent intent, String resolvedType, Bundle bOptions) {
22208             checkCaller();
22209
22210             int callingUser = UserHandle.getCallingUserId();
22211             TaskRecord tr;
22212             IApplicationThread appThread;
22213             synchronized (ActivityManagerService.this) {
22214                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22215                 if (tr == null) {
22216                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22217                 }
22218                 appThread = ApplicationThreadNative.asInterface(whoThread);
22219                 if (appThread == null) {
22220                     throw new IllegalArgumentException("Bad app thread " + appThread);
22221                 }
22222             }
22223             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22224                     resolvedType, null, null, null, null, 0, 0, null, null,
22225                     null, bOptions, false, callingUser, null, tr);
22226         }
22227
22228         @Override
22229         public void setExcludeFromRecents(boolean exclude) {
22230             checkCaller();
22231
22232             synchronized (ActivityManagerService.this) {
22233                 long origId = Binder.clearCallingIdentity();
22234                 try {
22235                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22236                     if (tr == null) {
22237                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22238                     }
22239                     Intent intent = tr.getBaseIntent();
22240                     if (exclude) {
22241                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22242                     } else {
22243                         intent.setFlags(intent.getFlags()
22244                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22245                     }
22246                 } finally {
22247                     Binder.restoreCallingIdentity(origId);
22248                 }
22249             }
22250         }
22251     }
22252
22253     /**
22254      * Kill processes for the user with id userId and that depend on the package named packageName
22255      */
22256     @Override
22257     public void killPackageDependents(String packageName, int userId) {
22258         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22259         if (packageName == null) {
22260             throw new NullPointerException(
22261                     "Cannot kill the dependents of a package without its name.");
22262         }
22263
22264         long callingId = Binder.clearCallingIdentity();
22265         IPackageManager pm = AppGlobals.getPackageManager();
22266         int pkgUid = -1;
22267         try {
22268             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22269         } catch (RemoteException e) {
22270         }
22271         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22272             throw new IllegalArgumentException(
22273                     "Cannot kill dependents of non-existing package " + packageName);
22274         }
22275         try {
22276             synchronized(this) {
22277                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22278                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22279                         "dep: " + packageName);
22280             }
22281         } finally {
22282             Binder.restoreCallingIdentity(callingId);
22283         }
22284     }
22285
22286     @Override
22287     public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22288         final int userId = intent.getCreatorUserHandle().getIdentifier();
22289         if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22290             return false;
22291         }
22292         IIntentSender target = intent.getTarget();
22293         if (!(target instanceof PendingIntentRecord)) {
22294             return false;
22295         }
22296         final PendingIntentRecord record = (PendingIntentRecord) target;
22297         final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22298                 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22299         // For direct boot aware activities, they can be shown without triggering a work challenge
22300         // before the profile user is unlocked.
22301         return rInfo != null && rInfo.activityInfo != null;
22302     }
22303 }