OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[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     }
647
648     private static final class PriorityState {
649         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
650         // the current thread is currently in. When it drops down to zero, we will no longer boost
651         // the thread's priority.
652         private int regionCounter = 0;
653
654         // The thread's previous priority before boosting.
655         private int prevPriority = Integer.MIN_VALUE;
656     }
657
658     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
659         @Override protected PriorityState initialValue() {
660             return new PriorityState();
661         }
662     };
663
664     static void boostPriorityForLockedSection() {
665         int tid = Process.myTid();
666         int prevPriority = Process.getThreadPriority(tid);
667         PriorityState state = sThreadPriorityState.get();
668         if (state.regionCounter == 0 && prevPriority > -2) {
669             state.prevPriority = prevPriority;
670             Process.setThreadPriority(tid, -2);
671         }
672         state.regionCounter++;
673     }
674
675     static void resetPriorityAfterLockedSection() {
676         PriorityState state = sThreadPriorityState.get();
677         state.regionCounter--;
678         if (state.regionCounter == 0 && state.prevPriority > -2) {
679             Process.setThreadPriority(Process.myTid(), state.prevPriority);
680         }
681     }
682
683     public class PendingAssistExtras extends Binder implements Runnable {
684         public final ActivityRecord activity;
685         public final Bundle extras;
686         public final Intent intent;
687         public final String hint;
688         public final IResultReceiver receiver;
689         public final int userHandle;
690         public boolean haveResult = false;
691         public Bundle result = null;
692         public AssistStructure structure = null;
693         public AssistContent content = null;
694         public Bundle receiverExtras;
695
696         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
697                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
698             activity = _activity;
699             extras = _extras;
700             intent = _intent;
701             hint = _hint;
702             receiver = _receiver;
703             receiverExtras = _receiverExtras;
704             userHandle = _userHandle;
705         }
706         @Override
707         public void run() {
708             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
709             synchronized (this) {
710                 haveResult = true;
711                 notifyAll();
712             }
713             pendingAssistExtrasTimedOut(this);
714         }
715     }
716
717     final ArrayList<PendingAssistExtras> mPendingAssistExtras
718             = new ArrayList<PendingAssistExtras>();
719
720     /**
721      * Process management.
722      */
723     final ProcessList mProcessList = new ProcessList();
724
725     /**
726      * All of the applications we currently have running organized by name.
727      * The keys are strings of the application package name (as
728      * returned by the package manager), and the keys are ApplicationRecord
729      * objects.
730      */
731     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
732
733     /**
734      * Tracking long-term execution of processes to look for abuse and other
735      * bad app behavior.
736      */
737     final ProcessStatsService mProcessStats;
738
739     /**
740      * The currently running isolated processes.
741      */
742     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
743
744     /**
745      * Counter for assigning isolated process uids, to avoid frequently reusing the
746      * same ones.
747      */
748     int mNextIsolatedProcessUid = 0;
749
750     /**
751      * The currently running heavy-weight process, if any.
752      */
753     ProcessRecord mHeavyWeightProcess = null;
754
755     /**
756      * All of the processes we currently have running organized by pid.
757      * The keys are the pid running the application.
758      *
759      * <p>NOTE: This object is protected by its own lock, NOT the global
760      * activity manager lock!
761      */
762     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
763
764     /**
765      * All of the processes that have been forced to be foreground.  The key
766      * is the pid of the caller who requested it (we hold a death
767      * link on it).
768      */
769     abstract class ForegroundToken implements IBinder.DeathRecipient {
770         int pid;
771         IBinder token;
772     }
773     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
774
775     /**
776      * List of records for processes that someone had tried to start before the
777      * system was ready.  We don't start them at that point, but ensure they
778      * are started by the time booting is complete.
779      */
780     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
781
782     /**
783      * List of persistent applications that are in the process
784      * of being started.
785      */
786     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
787
788     /**
789      * Processes that are being forcibly torn down.
790      */
791     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
792
793     /**
794      * List of running applications, sorted by recent usage.
795      * The first entry in the list is the least recently used.
796      */
797     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
798
799     /**
800      * Where in mLruProcesses that the processes hosting activities start.
801      */
802     int mLruProcessActivityStart = 0;
803
804     /**
805      * Where in mLruProcesses that the processes hosting services start.
806      * This is after (lower index) than mLruProcessesActivityStart.
807      */
808     int mLruProcessServiceStart = 0;
809
810     /**
811      * List of processes that should gc as soon as things are idle.
812      */
813     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
814
815     /**
816      * Processes we want to collect PSS data from.
817      */
818     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
819
820     private boolean mBinderTransactionTrackingEnabled = false;
821
822     /**
823      * Last time we requested PSS data of all processes.
824      */
825     long mLastFullPssTime = SystemClock.uptimeMillis();
826
827     /**
828      * If set, the next time we collect PSS data we should do a full collection
829      * with data from native processes and the kernel.
830      */
831     boolean mFullPssPending = false;
832
833     /**
834      * This is the process holding what we currently consider to be
835      * the "home" activity.
836      */
837     ProcessRecord mHomeProcess;
838
839     /**
840      * This is the process holding the activity the user last visited that
841      * is in a different process from the one they are currently in.
842      */
843     ProcessRecord mPreviousProcess;
844
845     /**
846      * The time at which the previous process was last visible.
847      */
848     long mPreviousProcessVisibleTime;
849
850     /**
851      * Track all uids that have actively running processes.
852      */
853     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
854
855     /**
856      * This is for verifying the UID report flow.
857      */
858     static final boolean VALIDATE_UID_STATES = true;
859     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
860
861     /**
862      * Packages that the user has asked to have run in screen size
863      * compatibility mode instead of filling the screen.
864      */
865     final CompatModePackages mCompatModePackages;
866
867     /**
868      * Set of IntentSenderRecord objects that are currently active.
869      */
870     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
871             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
872
873     /**
874      * Fingerprints (hashCode()) of stack traces that we've
875      * already logged DropBox entries for.  Guarded by itself.  If
876      * something (rogue user app) forces this over
877      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
878      */
879     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
880     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
881
882     /**
883      * Strict Mode background batched logging state.
884      *
885      * The string buffer is guarded by itself, and its lock is also
886      * used to determine if another batched write is already
887      * in-flight.
888      */
889     private final StringBuilder mStrictModeBuffer = new StringBuilder();
890
891     /**
892      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
893      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
894      */
895     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
896
897     /**
898      * Resolver for broadcast intents to registered receivers.
899      * Holds BroadcastFilter (subclass of IntentFilter).
900      */
901     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
902             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
903         @Override
904         protected boolean allowFilterResult(
905                 BroadcastFilter filter, List<BroadcastFilter> dest) {
906             IBinder target = filter.receiverList.receiver.asBinder();
907             for (int i = dest.size() - 1; i >= 0; i--) {
908                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
909                     return false;
910                 }
911             }
912             return true;
913         }
914
915         @Override
916         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
917             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
918                     || userId == filter.owningUserId) {
919                 return super.newResult(filter, match, userId);
920             }
921             return null;
922         }
923
924         @Override
925         protected BroadcastFilter[] newArray(int size) {
926             return new BroadcastFilter[size];
927         }
928
929         @Override
930         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
931             return packageName.equals(filter.packageName);
932         }
933     };
934
935     /**
936      * State of all active sticky broadcasts per user.  Keys are the action of the
937      * sticky Intent, values are an ArrayList of all broadcasted intents with
938      * that action (which should usually be one).  The SparseArray is keyed
939      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
940      * for stickies that are sent to all users.
941      */
942     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
943             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
944
945     final ActiveServices mServices;
946
947     final static class Association {
948         final int mSourceUid;
949         final String mSourceProcess;
950         final int mTargetUid;
951         final ComponentName mTargetComponent;
952         final String mTargetProcess;
953
954         int mCount;
955         long mTime;
956
957         int mNesting;
958         long mStartTime;
959
960         // states of the source process when the bind occurred.
961         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
962         long mLastStateUptime;
963         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
964                 - ActivityManager.MIN_PROCESS_STATE+1];
965
966         Association(int sourceUid, String sourceProcess, int targetUid,
967                 ComponentName targetComponent, String targetProcess) {
968             mSourceUid = sourceUid;
969             mSourceProcess = sourceProcess;
970             mTargetUid = targetUid;
971             mTargetComponent = targetComponent;
972             mTargetProcess = targetProcess;
973         }
974     }
975
976     /**
977      * When service association tracking is enabled, this is all of the associations we
978      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
979      * -> association data.
980      */
981     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
982             mAssociations = new SparseArray<>();
983     boolean mTrackingAssociations;
984
985     /**
986      * Backup/restore process management
987      */
988     String mBackupAppName = null;
989     BackupRecord mBackupTarget = null;
990
991     final ProviderMap mProviderMap;
992
993     /**
994      * List of content providers who have clients waiting for them.  The
995      * application is currently being launched and the provider will be
996      * removed from this list once it is published.
997      */
998     final ArrayList<ContentProviderRecord> mLaunchingProviders
999             = new ArrayList<ContentProviderRecord>();
1000
1001     /**
1002      * File storing persisted {@link #mGrantedUriPermissions}.
1003      */
1004     private final AtomicFile mGrantFile;
1005
1006     /** XML constants used in {@link #mGrantFile} */
1007     private static final String TAG_URI_GRANTS = "uri-grants";
1008     private static final String TAG_URI_GRANT = "uri-grant";
1009     private static final String ATTR_USER_HANDLE = "userHandle";
1010     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1011     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1012     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1013     private static final String ATTR_TARGET_PKG = "targetPkg";
1014     private static final String ATTR_URI = "uri";
1015     private static final String ATTR_MODE_FLAGS = "modeFlags";
1016     private static final String ATTR_CREATED_TIME = "createdTime";
1017     private static final String ATTR_PREFIX = "prefix";
1018
1019     /**
1020      * Global set of specific {@link Uri} permissions that have been granted.
1021      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1022      * to {@link UriPermission#uri} to {@link UriPermission}.
1023      */
1024     @GuardedBy("this")
1025     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1026             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1027
1028     public static class GrantUri {
1029         public final int sourceUserId;
1030         public final Uri uri;
1031         public boolean prefix;
1032
1033         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1034             this.sourceUserId = sourceUserId;
1035             this.uri = uri;
1036             this.prefix = prefix;
1037         }
1038
1039         @Override
1040         public int hashCode() {
1041             int hashCode = 1;
1042             hashCode = 31 * hashCode + sourceUserId;
1043             hashCode = 31 * hashCode + uri.hashCode();
1044             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1045             return hashCode;
1046         }
1047
1048         @Override
1049         public boolean equals(Object o) {
1050             if (o instanceof GrantUri) {
1051                 GrantUri other = (GrantUri) o;
1052                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1053                         && prefix == other.prefix;
1054             }
1055             return false;
1056         }
1057
1058         @Override
1059         public String toString() {
1060             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1061             if (prefix) result += " [prefix]";
1062             return result;
1063         }
1064
1065         public String toSafeString() {
1066             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1067             if (prefix) result += " [prefix]";
1068             return result;
1069         }
1070
1071         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1072             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1073                     ContentProvider.getUriWithoutUserId(uri), false);
1074         }
1075     }
1076
1077     CoreSettingsObserver mCoreSettingsObserver;
1078
1079     FontScaleSettingObserver mFontScaleSettingObserver;
1080
1081     private final class FontScaleSettingObserver extends ContentObserver {
1082         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1083
1084         public FontScaleSettingObserver() {
1085             super(mHandler);
1086             ContentResolver resolver = mContext.getContentResolver();
1087             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1088         }
1089
1090         @Override
1091         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1092             if (mFontScaleUri.equals(uri)) {
1093                 updateFontScaleIfNeeded(userId);
1094             }
1095         }
1096     }
1097
1098     /**
1099      * Thread-local storage used to carry caller permissions over through
1100      * indirect content-provider access.
1101      */
1102     private class Identity {
1103         public final IBinder token;
1104         public final int pid;
1105         public final int uid;
1106
1107         Identity(IBinder _token, int _pid, int _uid) {
1108             token = _token;
1109             pid = _pid;
1110             uid = _uid;
1111         }
1112     }
1113
1114     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1115
1116     /**
1117      * All information we have collected about the runtime performance of
1118      * any user id that can impact battery performance.
1119      */
1120     final BatteryStatsService mBatteryStatsService;
1121
1122     /**
1123      * Information about component usage
1124      */
1125     UsageStatsManagerInternal mUsageStatsService;
1126
1127     /**
1128      * Access to DeviceIdleController service.
1129      */
1130     DeviceIdleController.LocalService mLocalDeviceIdleController;
1131
1132     /**
1133      * Information about and control over application operations
1134      */
1135     final AppOpsService mAppOpsService;
1136
1137     /**
1138      * Current configuration information.  HistoryRecord objects are given
1139      * a reference to this object to indicate which configuration they are
1140      * currently running in, so this object must be kept immutable.
1141      */
1142     Configuration mConfiguration = new Configuration();
1143
1144     /**
1145      * Current sequencing integer of the configuration, for skipping old
1146      * configurations.
1147      */
1148     int mConfigurationSeq = 0;
1149
1150     boolean mSuppressResizeConfigChanges = false;
1151
1152     /**
1153      * Hardware-reported OpenGLES version.
1154      */
1155     final int GL_ES_VERSION;
1156
1157     /**
1158      * List of initialization arguments to pass to all processes when binding applications to them.
1159      * For example, references to the commonly used services.
1160      */
1161     HashMap<String, IBinder> mAppBindArgs;
1162     HashMap<String, IBinder> mIsolatedAppBindArgs;
1163
1164     /**
1165      * Temporary to avoid allocations.  Protected by main lock.
1166      */
1167     final StringBuilder mStringBuilder = new StringBuilder(256);
1168
1169     /**
1170      * Used to control how we initialize the service.
1171      */
1172     ComponentName mTopComponent;
1173     String mTopAction = Intent.ACTION_MAIN;
1174     String mTopData;
1175
1176     volatile boolean mProcessesReady = false;
1177     volatile boolean mSystemReady = false;
1178     volatile boolean mOnBattery = false;
1179     volatile int mFactoryTest;
1180
1181     @GuardedBy("this") boolean mBooting = false;
1182     @GuardedBy("this") boolean mCallFinishBooting = false;
1183     @GuardedBy("this") boolean mBootAnimationComplete = false;
1184     @GuardedBy("this") boolean mLaunchWarningShown = false;
1185     @GuardedBy("this") boolean mCheckedForSetup = false;
1186
1187     Context mContext;
1188
1189     /**
1190      * The time at which we will allow normal application switches again,
1191      * after a call to {@link #stopAppSwitches()}.
1192      */
1193     long mAppSwitchesAllowedTime;
1194
1195     /**
1196      * This is set to true after the first switch after mAppSwitchesAllowedTime
1197      * is set; any switches after that will clear the time.
1198      */
1199     boolean mDidAppSwitch;
1200
1201     /**
1202      * Last time (in realtime) at which we checked for power usage.
1203      */
1204     long mLastPowerCheckRealtime;
1205
1206     /**
1207      * Last time (in uptime) at which we checked for power usage.
1208      */
1209     long mLastPowerCheckUptime;
1210
1211     /**
1212      * Set while we are wanting to sleep, to prevent any
1213      * activities from being started/resumed.
1214      */
1215     private boolean mSleeping = false;
1216
1217     /**
1218      * The process state used for processes that are running the top activities.
1219      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1220      */
1221     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1222
1223     /**
1224      * Set while we are running a voice interaction.  This overrides
1225      * sleeping while it is active.
1226      */
1227     private IVoiceInteractionSession mRunningVoice;
1228
1229     /**
1230      * For some direct access we need to power manager.
1231      */
1232     PowerManagerInternal mLocalPowerManager;
1233
1234     /**
1235      * We want to hold a wake lock while running a voice interaction session, since
1236      * this may happen with the screen off and we need to keep the CPU running to
1237      * be able to continue to interact with the user.
1238      */
1239     PowerManager.WakeLock mVoiceWakeLock;
1240
1241     /**
1242      * State of external calls telling us if the device is awake or asleep.
1243      */
1244     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1245
1246     /**
1247      * A list of tokens that cause the top activity to be put to sleep.
1248      * They are used by components that may hide and block interaction with underlying
1249      * activities.
1250      */
1251     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1252
1253     static final int LOCK_SCREEN_HIDDEN = 0;
1254     static final int LOCK_SCREEN_LEAVING = 1;
1255     static final int LOCK_SCREEN_SHOWN = 2;
1256     /**
1257      * State of external call telling us if the lock screen is shown.
1258      */
1259     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1260
1261     /**
1262      * Set if we are shutting down the system, similar to sleeping.
1263      */
1264     boolean mShuttingDown = false;
1265
1266     /**
1267      * Current sequence id for oom_adj computation traversal.
1268      */
1269     int mAdjSeq = 0;
1270
1271     /**
1272      * Current sequence id for process LRU updating.
1273      */
1274     int mLruSeq = 0;
1275
1276     /**
1277      * Keep track of the non-cached/empty process we last found, to help
1278      * determine how to distribute cached/empty processes next time.
1279      */
1280     int mNumNonCachedProcs = 0;
1281
1282     /**
1283      * Keep track of the number of cached hidden procs, to balance oom adj
1284      * distribution between those and empty procs.
1285      */
1286     int mNumCachedHiddenProcs = 0;
1287
1288     /**
1289      * Keep track of the number of service processes we last found, to
1290      * determine on the next iteration which should be B services.
1291      */
1292     int mNumServiceProcs = 0;
1293     int mNewNumAServiceProcs = 0;
1294     int mNewNumServiceProcs = 0;
1295
1296     /**
1297      * Allow the current computed overall memory level of the system to go down?
1298      * This is set to false when we are killing processes for reasons other than
1299      * memory management, so that the now smaller process list will not be taken as
1300      * an indication that memory is tighter.
1301      */
1302     boolean mAllowLowerMemLevel = false;
1303
1304     /**
1305      * The last computed memory level, for holding when we are in a state that
1306      * processes are going away for other reasons.
1307      */
1308     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1309
1310     /**
1311      * The last total number of process we have, to determine if changes actually look
1312      * like a shrinking number of process due to lower RAM.
1313      */
1314     int mLastNumProcesses;
1315
1316     /**
1317      * The uptime of the last time we performed idle maintenance.
1318      */
1319     long mLastIdleTime = SystemClock.uptimeMillis();
1320
1321     /**
1322      * Total time spent with RAM that has been added in the past since the last idle time.
1323      */
1324     long mLowRamTimeSinceLastIdle = 0;
1325
1326     /**
1327      * If RAM is currently low, when that horrible situation started.
1328      */
1329     long mLowRamStartTime = 0;
1330
1331     /**
1332      * For reporting to battery stats the current top application.
1333      */
1334     private String mCurResumedPackage = null;
1335     private int mCurResumedUid = -1;
1336
1337     /**
1338      * For reporting to battery stats the apps currently running foreground
1339      * service.  The ProcessMap is package/uid tuples; each of these contain
1340      * an array of the currently foreground processes.
1341      */
1342     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1343             = new ProcessMap<ArrayList<ProcessRecord>>();
1344
1345     /**
1346      * This is set if we had to do a delayed dexopt of an app before launching
1347      * it, to increase the ANR timeouts in that case.
1348      */
1349     boolean mDidDexOpt;
1350
1351     /**
1352      * Set if the systemServer made a call to enterSafeMode.
1353      */
1354     boolean mSafeMode;
1355
1356     /**
1357      * If true, we are running under a test environment so will sample PSS from processes
1358      * much more rapidly to try to collect better data when the tests are rapidly
1359      * running through apps.
1360      */
1361     boolean mTestPssMode = false;
1362
1363     String mDebugApp = null;
1364     boolean mWaitForDebugger = false;
1365     boolean mDebugTransient = false;
1366     String mOrigDebugApp = null;
1367     boolean mOrigWaitForDebugger = false;
1368     boolean mAlwaysFinishActivities = false;
1369     boolean mLenientBackgroundCheck = false;
1370     boolean mForceResizableActivities;
1371     boolean mSupportsMultiWindow;
1372     boolean mSupportsFreeformWindowManagement;
1373     boolean mSupportsPictureInPicture;
1374     boolean mSupportsLeanbackOnly;
1375     Rect mDefaultPinnedStackBounds;
1376     IActivityController mController = null;
1377     boolean mControllerIsAMonkey = false;
1378     String mProfileApp = null;
1379     ProcessRecord mProfileProc = null;
1380     String mProfileFile;
1381     ParcelFileDescriptor mProfileFd;
1382     int mSamplingInterval = 0;
1383     boolean mAutoStopProfiler = false;
1384     int mProfileType = 0;
1385     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386     String mMemWatchDumpProcName;
1387     String mMemWatchDumpFile;
1388     int mMemWatchDumpPid;
1389     int mMemWatchDumpUid;
1390     String mTrackAllocationApp = null;
1391     String mNativeDebuggingApp = null;
1392
1393     final long[] mTmpLong = new long[2];
1394
1395     static final class ProcessChangeItem {
1396         static final int CHANGE_ACTIVITIES = 1<<0;
1397         static final int CHANGE_PROCESS_STATE = 1<<1;
1398         int changes;
1399         int uid;
1400         int pid;
1401         int processState;
1402         boolean foregroundActivities;
1403     }
1404
1405     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1406     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1407
1408     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1409     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1410
1411     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1412     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1413
1414     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1415     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1416
1417     /**
1418      * Runtime CPU use collection thread.  This object's lock is used to
1419      * perform synchronization with the thread (notifying it to run).
1420      */
1421     final Thread mProcessCpuThread;
1422
1423     /**
1424      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1425      * Must acquire this object's lock when accessing it.
1426      * NOTE: this lock will be held while doing long operations (trawling
1427      * through all processes in /proc), so it should never be acquired by
1428      * any critical paths such as when holding the main activity manager lock.
1429      */
1430     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1431             MONITOR_THREAD_CPU_USAGE);
1432     final AtomicLong mLastCpuTime = new AtomicLong(0);
1433     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1434
1435     long mLastWriteTime = 0;
1436
1437     /**
1438      * Used to retain an update lock when the foreground activity is in
1439      * immersive mode.
1440      */
1441     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1442
1443     /**
1444      * Set to true after the system has finished booting.
1445      */
1446     boolean mBooted = false;
1447
1448     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1449     int mProcessLimitOverride = -1;
1450
1451     WindowManagerService mWindowManager;
1452     final ActivityThread mSystemThread;
1453
1454     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1455         final ProcessRecord mApp;
1456         final int mPid;
1457         final IApplicationThread mAppThread;
1458
1459         AppDeathRecipient(ProcessRecord app, int pid,
1460                 IApplicationThread thread) {
1461             if (DEBUG_ALL) Slog.v(
1462                 TAG, "New death recipient " + this
1463                 + " for thread " + thread.asBinder());
1464             mApp = app;
1465             mPid = pid;
1466             mAppThread = thread;
1467         }
1468
1469         @Override
1470         public void binderDied() {
1471             if (DEBUG_ALL) Slog.v(
1472                 TAG, "Death received in " + this
1473                 + " for thread " + mAppThread.asBinder());
1474             synchronized(ActivityManagerService.this) {
1475                 appDiedLocked(mApp, mPid, mAppThread, true);
1476             }
1477         }
1478     }
1479
1480     static final int SHOW_ERROR_UI_MSG = 1;
1481     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1482     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1483     static final int UPDATE_CONFIGURATION_MSG = 4;
1484     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1485     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1486     static final int SERVICE_TIMEOUT_MSG = 12;
1487     static final int UPDATE_TIME_ZONE = 13;
1488     static final int SHOW_UID_ERROR_UI_MSG = 14;
1489     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1490     static final int PROC_START_TIMEOUT_MSG = 20;
1491     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1492     static final int KILL_APPLICATION_MSG = 22;
1493     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1494     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1495     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1496     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1497     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1498     static final int CLEAR_DNS_CACHE_MSG = 28;
1499     static final int UPDATE_HTTP_PROXY_MSG = 29;
1500     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1501     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1502     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1503     static final int REPORT_MEM_USAGE_MSG = 33;
1504     static final int REPORT_USER_SWITCH_MSG = 34;
1505     static final int CONTINUE_USER_SWITCH_MSG = 35;
1506     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1507     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1508     static final int PERSIST_URI_GRANTS_MSG = 38;
1509     static final int REQUEST_ALL_PSS_MSG = 39;
1510     static final int START_PROFILES_MSG = 40;
1511     static final int UPDATE_TIME = 41;
1512     static final int SYSTEM_USER_START_MSG = 42;
1513     static final int SYSTEM_USER_CURRENT_MSG = 43;
1514     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1515     static final int FINISH_BOOTING_MSG = 45;
1516     static final int START_USER_SWITCH_UI_MSG = 46;
1517     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1518     static final int DISMISS_DIALOG_UI_MSG = 48;
1519     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1520     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1521     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1522     static final int DELETE_DUMPHEAP_MSG = 52;
1523     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1524     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1525     static final int REPORT_TIME_TRACKER_MSG = 55;
1526     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1527     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1528     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1529     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1530     static final int IDLE_UIDS_MSG = 60;
1531     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1532     static final int LOG_STACK_STATE = 62;
1533     static final int VR_MODE_CHANGE_MSG = 63;
1534     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1535     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1536     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1537     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1538     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1539     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1540     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1541
1542     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1543     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1544     static final int FIRST_COMPAT_MODE_MSG = 300;
1545     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1546
1547     static ServiceThread sKillThread = null;
1548     static KillHandler sKillHandler = null;
1549
1550     CompatModeDialog mCompatModeDialog;
1551     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1552     long mLastMemUsageReportTime = 0;
1553
1554     /**
1555      * Flag whether the current user is a "monkey", i.e. whether
1556      * the UI is driven by a UI automation tool.
1557      */
1558     private boolean mUserIsMonkey;
1559
1560     /** Flag whether the device has a Recents UI */
1561     boolean mHasRecents;
1562
1563     /** The dimensions of the thumbnails in the Recents UI. */
1564     int mThumbnailWidth;
1565     int mThumbnailHeight;
1566     float mFullscreenThumbnailScale;
1567
1568     final ServiceThread mHandlerThread;
1569     final MainHandler mHandler;
1570     final UiHandler mUiHandler;
1571
1572     PackageManagerInternal mPackageManagerInt;
1573
1574     // VoiceInteraction session ID that changes for each new request except when
1575     // being called for multiwindow assist in a single session.
1576     private int mViSessionId = 1000;
1577
1578     final class KillHandler extends Handler {
1579         static final int KILL_PROCESS_GROUP_MSG = 4000;
1580
1581         public KillHandler(Looper looper) {
1582             super(looper, null, true);
1583         }
1584
1585         @Override
1586         public void handleMessage(Message msg) {
1587             switch (msg.what) {
1588                 case KILL_PROCESS_GROUP_MSG:
1589                 {
1590                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1591                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1592                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1593                 }
1594                 break;
1595
1596                 default:
1597                     super.handleMessage(msg);
1598             }
1599         }
1600     }
1601
1602     final class UiHandler extends Handler {
1603         public UiHandler() {
1604             super(com.android.server.UiThread.get().getLooper(), null, true);
1605         }
1606
1607         @Override
1608         public void handleMessage(Message msg) {
1609             switch (msg.what) {
1610             case SHOW_ERROR_UI_MSG: {
1611                 mAppErrors.handleShowAppErrorUi(msg);
1612                 ensureBootCompleted();
1613             } break;
1614             case SHOW_NOT_RESPONDING_UI_MSG: {
1615                 mAppErrors.handleShowAnrUi(msg);
1616                 ensureBootCompleted();
1617             } break;
1618             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1619                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1620                 synchronized (ActivityManagerService.this) {
1621                     ProcessRecord proc = (ProcessRecord) data.get("app");
1622                     if (proc == null) {
1623                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1624                         break;
1625                     }
1626                     if (proc.crashDialog != null) {
1627                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1628                         return;
1629                     }
1630                     AppErrorResult res = (AppErrorResult) data.get("result");
1631                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1632                         Dialog d = new StrictModeViolationDialog(mContext,
1633                                 ActivityManagerService.this, res, proc);
1634                         d.show();
1635                         proc.crashDialog = d;
1636                     } else {
1637                         // The device is asleep, so just pretend that the user
1638                         // saw a crash dialog and hit "force quit".
1639                         res.set(0);
1640                     }
1641                 }
1642                 ensureBootCompleted();
1643             } break;
1644             case SHOW_FACTORY_ERROR_UI_MSG: {
1645                 Dialog d = new FactoryErrorDialog(
1646                     mContext, msg.getData().getCharSequence("msg"));
1647                 d.show();
1648                 ensureBootCompleted();
1649             } break;
1650             case WAIT_FOR_DEBUGGER_UI_MSG: {
1651                 synchronized (ActivityManagerService.this) {
1652                     ProcessRecord app = (ProcessRecord)msg.obj;
1653                     if (msg.arg1 != 0) {
1654                         if (!app.waitedForDebugger) {
1655                             Dialog d = new AppWaitingForDebuggerDialog(
1656                                     ActivityManagerService.this,
1657                                     mContext, app);
1658                             app.waitDialog = d;
1659                             app.waitedForDebugger = true;
1660                             d.show();
1661                         }
1662                     } else {
1663                         if (app.waitDialog != null) {
1664                             app.waitDialog.dismiss();
1665                             app.waitDialog = null;
1666                         }
1667                     }
1668                 }
1669             } break;
1670             case SHOW_UID_ERROR_UI_MSG: {
1671                 if (mShowDialogs) {
1672                     AlertDialog d = new BaseErrorDialog(mContext);
1673                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1674                     d.setCancelable(false);
1675                     d.setTitle(mContext.getText(R.string.android_system_label));
1676                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1677                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1678                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1679                     d.show();
1680                 }
1681             } break;
1682             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1683                 if (mShowDialogs) {
1684                     AlertDialog d = new BaseErrorDialog(mContext);
1685                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                     d.setCancelable(false);
1687                     d.setTitle(mContext.getText(R.string.android_system_label));
1688                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1689                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                     d.show();
1692                 }
1693             } break;
1694             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1695                 synchronized (ActivityManagerService.this) {
1696                     ActivityRecord ar = (ActivityRecord) msg.obj;
1697                     if (mCompatModeDialog != null) {
1698                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1699                                 ar.info.applicationInfo.packageName)) {
1700                             return;
1701                         }
1702                         mCompatModeDialog.dismiss();
1703                         mCompatModeDialog = null;
1704                     }
1705                     if (ar != null && false) {
1706                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1707                                 ar.packageName)) {
1708                             int mode = mCompatModePackages.computeCompatModeLocked(
1709                                     ar.info.applicationInfo);
1710                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1711                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1712                                 mCompatModeDialog = new CompatModeDialog(
1713                                         ActivityManagerService.this, mContext,
1714                                         ar.info.applicationInfo);
1715                                 mCompatModeDialog.show();
1716                             }
1717                         }
1718                     }
1719                 }
1720                 break;
1721             }
1722             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1723                 synchronized (ActivityManagerService.this) {
1724                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1725                     if (mUnsupportedDisplaySizeDialog != null) {
1726                         mUnsupportedDisplaySizeDialog.dismiss();
1727                         mUnsupportedDisplaySizeDialog = null;
1728                     }
1729                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1730                             ar.packageName)) {
1731                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1732                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1733                         mUnsupportedDisplaySizeDialog.show();
1734                     }
1735                 }
1736                 break;
1737             }
1738             case START_USER_SWITCH_UI_MSG: {
1739                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1740                 break;
1741             }
1742             case DISMISS_DIALOG_UI_MSG: {
1743                 final Dialog d = (Dialog) msg.obj;
1744                 d.dismiss();
1745                 break;
1746             }
1747             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1748                 dispatchProcessesChanged();
1749                 break;
1750             }
1751             case DISPATCH_PROCESS_DIED_UI_MSG: {
1752                 final int pid = msg.arg1;
1753                 final int uid = msg.arg2;
1754                 dispatchProcessDied(pid, uid);
1755                 break;
1756             }
1757             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1758                 dispatchUidsChanged();
1759             } break;
1760             }
1761         }
1762     }
1763
1764     final class MainHandler extends Handler {
1765         public MainHandler(Looper looper) {
1766             super(looper, null, true);
1767         }
1768
1769         @Override
1770         public void handleMessage(Message msg) {
1771             switch (msg.what) {
1772             case UPDATE_CONFIGURATION_MSG: {
1773                 final ContentResolver resolver = mContext.getContentResolver();
1774                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1775                         msg.arg1);
1776             } break;
1777             case GC_BACKGROUND_PROCESSES_MSG: {
1778                 synchronized (ActivityManagerService.this) {
1779                     performAppGcsIfAppropriateLocked();
1780                 }
1781             } break;
1782             case SERVICE_TIMEOUT_MSG: {
1783                 if (mDidDexOpt) {
1784                     mDidDexOpt = false;
1785                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1786                     nmsg.obj = msg.obj;
1787                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1788                     return;
1789                 }
1790                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1791             } break;
1792             case UPDATE_TIME_ZONE: {
1793                 synchronized (ActivityManagerService.this) {
1794                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1795                         ProcessRecord r = mLruProcesses.get(i);
1796                         if (r.thread != null) {
1797                             try {
1798                                 r.thread.updateTimeZone();
1799                             } catch (RemoteException ex) {
1800                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1801                             }
1802                         }
1803                     }
1804                 }
1805             } break;
1806             case CLEAR_DNS_CACHE_MSG: {
1807                 synchronized (ActivityManagerService.this) {
1808                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1809                         ProcessRecord r = mLruProcesses.get(i);
1810                         if (r.thread != null) {
1811                             try {
1812                                 r.thread.clearDnsCache();
1813                             } catch (RemoteException ex) {
1814                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1815                             }
1816                         }
1817                     }
1818                 }
1819             } break;
1820             case UPDATE_HTTP_PROXY_MSG: {
1821                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1822                 String host = "";
1823                 String port = "";
1824                 String exclList = "";
1825                 Uri pacFileUrl = Uri.EMPTY;
1826                 if (proxy != null) {
1827                     host = proxy.getHost();
1828                     port = Integer.toString(proxy.getPort());
1829                     exclList = proxy.getExclusionListAsString();
1830                     pacFileUrl = proxy.getPacFileUrl();
1831                 }
1832                 synchronized (ActivityManagerService.this) {
1833                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1834                         ProcessRecord r = mLruProcesses.get(i);
1835                         if (r.thread != null) {
1836                             try {
1837                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1838                             } catch (RemoteException ex) {
1839                                 Slog.w(TAG, "Failed to update http proxy for: " +
1840                                         r.info.processName);
1841                             }
1842                         }
1843                     }
1844                 }
1845             } break;
1846             case PROC_START_TIMEOUT_MSG: {
1847                 if (mDidDexOpt) {
1848                     mDidDexOpt = false;
1849                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1850                     nmsg.obj = msg.obj;
1851                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1852                     return;
1853                 }
1854                 ProcessRecord app = (ProcessRecord)msg.obj;
1855                 synchronized (ActivityManagerService.this) {
1856                     processStartTimedOutLocked(app);
1857                 }
1858             } break;
1859             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1860                 ProcessRecord app = (ProcessRecord)msg.obj;
1861                 synchronized (ActivityManagerService.this) {
1862                     processContentProviderPublishTimedOutLocked(app);
1863                 }
1864             } break;
1865             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1866                 synchronized (ActivityManagerService.this) {
1867                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1868                 }
1869             } break;
1870             case KILL_APPLICATION_MSG: {
1871                 synchronized (ActivityManagerService.this) {
1872                     final int appId = msg.arg1;
1873                     final int userId = msg.arg2;
1874                     Bundle bundle = (Bundle)msg.obj;
1875                     String pkg = bundle.getString("pkg");
1876                     String reason = bundle.getString("reason");
1877                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1878                             false, userId, reason);
1879                 }
1880             } break;
1881             case FINALIZE_PENDING_INTENT_MSG: {
1882                 ((PendingIntentRecord)msg.obj).completeFinalize();
1883             } break;
1884             case POST_HEAVY_NOTIFICATION_MSG: {
1885                 INotificationManager inm = NotificationManager.getService();
1886                 if (inm == null) {
1887                     return;
1888                 }
1889
1890                 ActivityRecord root = (ActivityRecord)msg.obj;
1891                 ProcessRecord process = root.app;
1892                 if (process == null) {
1893                     return;
1894                 }
1895
1896                 try {
1897                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1898                     String text = mContext.getString(R.string.heavy_weight_notification,
1899                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1900                     Notification notification = new Notification.Builder(context)
1901                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1902                             .setWhen(0)
1903                             .setOngoing(true)
1904                             .setTicker(text)
1905                             .setColor(mContext.getColor(
1906                                     com.android.internal.R.color.system_notification_accent_color))
1907                             .setContentTitle(text)
1908                             .setContentText(
1909                                     mContext.getText(R.string.heavy_weight_notification_detail))
1910                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1911                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1912                                     new UserHandle(root.userId)))
1913                             .build();
1914                     try {
1915                         int[] outId = new int[1];
1916                         inm.enqueueNotificationWithTag("android", "android", null,
1917                                 R.string.heavy_weight_notification,
1918                                 notification, outId, root.userId);
1919                     } catch (RuntimeException e) {
1920                         Slog.w(ActivityManagerService.TAG,
1921                                 "Error showing notification for heavy-weight app", e);
1922                     } catch (RemoteException e) {
1923                     }
1924                 } catch (NameNotFoundException e) {
1925                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1926                 }
1927             } break;
1928             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1929                 INotificationManager inm = NotificationManager.getService();
1930                 if (inm == null) {
1931                     return;
1932                 }
1933                 try {
1934                     inm.cancelNotificationWithTag("android", null,
1935                             R.string.heavy_weight_notification,  msg.arg1);
1936                 } catch (RuntimeException e) {
1937                     Slog.w(ActivityManagerService.TAG,
1938                             "Error canceling notification for service", e);
1939                 } catch (RemoteException e) {
1940                 }
1941             } break;
1942             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1943                 synchronized (ActivityManagerService.this) {
1944                     checkExcessivePowerUsageLocked(true);
1945                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1946                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1947                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1948                 }
1949             } break;
1950             case REPORT_MEM_USAGE_MSG: {
1951                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1952                 Thread thread = new Thread() {
1953                     @Override public void run() {
1954                         reportMemUsage(memInfos);
1955                     }
1956                 };
1957                 thread.start();
1958                 break;
1959             }
1960             case REPORT_USER_SWITCH_MSG: {
1961                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1962                 break;
1963             }
1964             case CONTINUE_USER_SWITCH_MSG: {
1965                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1966                 break;
1967             }
1968             case USER_SWITCH_TIMEOUT_MSG: {
1969                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1970                 break;
1971             }
1972             case IMMERSIVE_MODE_LOCK_MSG: {
1973                 final boolean nextState = (msg.arg1 != 0);
1974                 if (mUpdateLock.isHeld() != nextState) {
1975                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1976                             "Applying new update lock state '" + nextState
1977                             + "' for " + (ActivityRecord)msg.obj);
1978                     if (nextState) {
1979                         mUpdateLock.acquire();
1980                     } else {
1981                         mUpdateLock.release();
1982                     }
1983                 }
1984                 break;
1985             }
1986             case PERSIST_URI_GRANTS_MSG: {
1987                 writeGrantedUriPermissions();
1988                 break;
1989             }
1990             case REQUEST_ALL_PSS_MSG: {
1991                 synchronized (ActivityManagerService.this) {
1992                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1993                 }
1994                 break;
1995             }
1996             case START_PROFILES_MSG: {
1997                 synchronized (ActivityManagerService.this) {
1998                     mUserController.startProfilesLocked();
1999                 }
2000                 break;
2001             }
2002             case UPDATE_TIME: {
2003                 synchronized (ActivityManagerService.this) {
2004                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2005                         ProcessRecord r = mLruProcesses.get(i);
2006                         if (r.thread != null) {
2007                             try {
2008                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2009                             } catch (RemoteException ex) {
2010                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2011                             }
2012                         }
2013                     }
2014                 }
2015                 break;
2016             }
2017             case SYSTEM_USER_START_MSG: {
2018                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2019                         Integer.toString(msg.arg1), msg.arg1);
2020                 mSystemServiceManager.startUser(msg.arg1);
2021                 break;
2022             }
2023             case SYSTEM_USER_UNLOCK_MSG: {
2024                 final int userId = msg.arg1;
2025                 mSystemServiceManager.unlockUser(userId);
2026                 synchronized (ActivityManagerService.this) {
2027                     mRecentTasks.loadUserRecentsLocked(userId);
2028                 }
2029                 if (userId == UserHandle.USER_SYSTEM) {
2030                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2031                 }
2032                 installEncryptionUnawareProviders(userId);
2033                 mUserController.finishUserUnlocked((UserState) msg.obj);
2034                 break;
2035             }
2036             case SYSTEM_USER_CURRENT_MSG: {
2037                 mBatteryStatsService.noteEvent(
2038                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2039                         Integer.toString(msg.arg2), msg.arg2);
2040                 mBatteryStatsService.noteEvent(
2041                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2042                         Integer.toString(msg.arg1), msg.arg1);
2043                 mSystemServiceManager.switchUser(msg.arg1);
2044                 break;
2045             }
2046             case ENTER_ANIMATION_COMPLETE_MSG: {
2047                 synchronized (ActivityManagerService.this) {
2048                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2049                     if (r != null && r.app != null && r.app.thread != null) {
2050                         try {
2051                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2052                         } catch (RemoteException e) {
2053                         }
2054                     }
2055                 }
2056                 break;
2057             }
2058             case FINISH_BOOTING_MSG: {
2059                 if (msg.arg1 != 0) {
2060                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2061                     finishBooting();
2062                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2063                 }
2064                 if (msg.arg2 != 0) {
2065                     enableScreenAfterBoot();
2066                 }
2067                 break;
2068             }
2069             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2070                 try {
2071                     Locale l = (Locale) msg.obj;
2072                     IBinder service = ServiceManager.getService("mount");
2073                     IMountService mountService = IMountService.Stub.asInterface(service);
2074                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2075                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2076                 } catch (RemoteException e) {
2077                     Log.e(TAG, "Error storing locale for decryption UI", e);
2078                 }
2079                 break;
2080             }
2081             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2082                 synchronized (ActivityManagerService.this) {
2083                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                         try {
2085                             // Make a one-way callback to the listener
2086                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2087                         } catch (RemoteException e){
2088                             // Handled by the RemoteCallbackList
2089                         }
2090                     }
2091                     mTaskStackListeners.finishBroadcast();
2092                 }
2093                 break;
2094             }
2095             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2096                 synchronized (ActivityManagerService.this) {
2097                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                         try {
2099                             // Make a one-way callback to the listener
2100                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2101                         } catch (RemoteException e){
2102                             // Handled by the RemoteCallbackList
2103                         }
2104                     }
2105                     mTaskStackListeners.finishBroadcast();
2106                 }
2107                 break;
2108             }
2109             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2110                 synchronized (ActivityManagerService.this) {
2111                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2112                         try {
2113                             // Make a one-way callback to the listener
2114                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2115                         } catch (RemoteException e){
2116                             // Handled by the RemoteCallbackList
2117                         }
2118                     }
2119                     mTaskStackListeners.finishBroadcast();
2120                 }
2121                 break;
2122             }
2123             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2124                 synchronized (ActivityManagerService.this) {
2125                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2126                         try {
2127                             // Make a one-way callback to the listener
2128                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2129                         } catch (RemoteException e){
2130                             // Handled by the RemoteCallbackList
2131                         }
2132                     }
2133                     mTaskStackListeners.finishBroadcast();
2134                 }
2135                 break;
2136             }
2137             case NOTIFY_FORCED_RESIZABLE_MSG: {
2138                 synchronized (ActivityManagerService.this) {
2139                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                         try {
2141                             // Make a one-way callback to the listener
2142                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2143                                     (String) msg.obj, msg.arg1);
2144                         } catch (RemoteException e){
2145                             // Handled by the RemoteCallbackList
2146                         }
2147                     }
2148                     mTaskStackListeners.finishBroadcast();
2149                 }
2150                 break;
2151             }
2152                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2153                     synchronized (ActivityManagerService.this) {
2154                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2155                             try {
2156                                 // Make a one-way callback to the listener
2157                                 mTaskStackListeners.getBroadcastItem(i)
2158                                         .onActivityDismissingDockedStack();
2159                             } catch (RemoteException e){
2160                                 // Handled by the RemoteCallbackList
2161                             }
2162                         }
2163                         mTaskStackListeners.finishBroadcast();
2164                     }
2165                     break;
2166                 }
2167             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2168                 final int uid = msg.arg1;
2169                 final byte[] firstPacket = (byte[]) msg.obj;
2170
2171                 synchronized (mPidsSelfLocked) {
2172                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2173                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2174                         if (p.uid == uid) {
2175                             try {
2176                                 p.thread.notifyCleartextNetwork(firstPacket);
2177                             } catch (RemoteException ignored) {
2178                             }
2179                         }
2180                     }
2181                 }
2182                 break;
2183             }
2184             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2185                 final String procName;
2186                 final int uid;
2187                 final long memLimit;
2188                 final String reportPackage;
2189                 synchronized (ActivityManagerService.this) {
2190                     procName = mMemWatchDumpProcName;
2191                     uid = mMemWatchDumpUid;
2192                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2193                     if (val == null) {
2194                         val = mMemWatchProcesses.get(procName, 0);
2195                     }
2196                     if (val != null) {
2197                         memLimit = val.first;
2198                         reportPackage = val.second;
2199                     } else {
2200                         memLimit = 0;
2201                         reportPackage = null;
2202                     }
2203                 }
2204                 if (procName == null) {
2205                     return;
2206                 }
2207
2208                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2209                         "Showing dump heap notification from " + procName + "/" + uid);
2210
2211                 INotificationManager inm = NotificationManager.getService();
2212                 if (inm == null) {
2213                     return;
2214                 }
2215
2216                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2217
2218
2219                 Intent deleteIntent = new Intent();
2220                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2221                 Intent intent = new Intent();
2222                 intent.setClassName("android", DumpHeapActivity.class.getName());
2223                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2224                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2225                 if (reportPackage != null) {
2226                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2227                 }
2228                 int userId = UserHandle.getUserId(uid);
2229                 Notification notification = new Notification.Builder(mContext)
2230                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2231                         .setWhen(0)
2232                         .setOngoing(true)
2233                         .setAutoCancel(true)
2234                         .setTicker(text)
2235                         .setColor(mContext.getColor(
2236                                 com.android.internal.R.color.system_notification_accent_color))
2237                         .setContentTitle(text)
2238                         .setContentText(
2239                                 mContext.getText(R.string.dump_heap_notification_detail))
2240                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2241                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2242                                 new UserHandle(userId)))
2243                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2244                                 deleteIntent, 0, UserHandle.SYSTEM))
2245                         .build();
2246
2247                 try {
2248                     int[] outId = new int[1];
2249                     inm.enqueueNotificationWithTag("android", "android", null,
2250                             R.string.dump_heap_notification,
2251                             notification, outId, userId);
2252                 } catch (RuntimeException e) {
2253                     Slog.w(ActivityManagerService.TAG,
2254                             "Error showing notification for dump heap", e);
2255                 } catch (RemoteException e) {
2256                 }
2257             } break;
2258             case DELETE_DUMPHEAP_MSG: {
2259                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2260                         DumpHeapActivity.JAVA_URI,
2261                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2262                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2263                         UserHandle.myUserId());
2264                 synchronized (ActivityManagerService.this) {
2265                     mMemWatchDumpFile = null;
2266                     mMemWatchDumpProcName = null;
2267                     mMemWatchDumpPid = -1;
2268                     mMemWatchDumpUid = -1;
2269                 }
2270             } break;
2271             case FOREGROUND_PROFILE_CHANGED_MSG: {
2272                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2273             } break;
2274             case REPORT_TIME_TRACKER_MSG: {
2275                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2276                 tracker.deliverResult(mContext);
2277             } break;
2278             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2279                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2280             } break;
2281             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2282                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2283                 try {
2284                     connection.shutdown();
2285                 } catch (RemoteException e) {
2286                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2287                 }
2288                 // Only a UiAutomation can set this flag and now that
2289                 // it is finished we make sure it is reset to its default.
2290                 mUserIsMonkey = false;
2291             } break;
2292             case APP_BOOST_DEACTIVATE_MSG: {
2293                 synchronized(ActivityManagerService.this) {
2294                     if (mIsBoosted) {
2295                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2296                             nativeMigrateFromBoost();
2297                             mIsBoosted = false;
2298                             mBoostStartTime = 0;
2299                         } else {
2300                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2301                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2302                         }
2303                     }
2304                 }
2305             } break;
2306             case IDLE_UIDS_MSG: {
2307                 idleUids();
2308             } break;
2309             case LOG_STACK_STATE: {
2310                 synchronized (ActivityManagerService.this) {
2311                     mStackSupervisor.logStackState();
2312                 }
2313             } break;
2314             case VR_MODE_CHANGE_MSG: {
2315                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2316                 final ActivityRecord r = (ActivityRecord) msg.obj;
2317                 boolean vrMode;
2318                 ComponentName requestedPackage;
2319                 ComponentName callingPackage;
2320                 int userId;
2321                 synchronized (ActivityManagerService.this) {
2322                     vrMode = r.requestedVrComponent != null;
2323                     requestedPackage = r.requestedVrComponent;
2324                     userId = r.userId;
2325                     callingPackage = r.info.getComponentName();
2326                     if (mInVrMode != vrMode) {
2327                         mInVrMode = vrMode;
2328                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2329                         if (r.app != null) {
2330                             ProcessRecord proc = r.app;
2331                             if (proc.vrThreadTid > 0) {
2332                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2333                                     try {
2334                                         if (mInVrMode == true) {
2335                                             Process.setThreadScheduler(proc.vrThreadTid,
2336                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2337                                         } else {
2338                                             Process.setThreadScheduler(proc.vrThreadTid,
2339                                                 Process.SCHED_OTHER, 0);
2340                                         }
2341                                     } catch (IllegalArgumentException e) {
2342                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2343                                                 + " not exist:\n" + e);
2344                                     }
2345                                 }
2346                             }
2347                         }
2348                     }
2349                 }
2350                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2351             } break;
2352             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2353                 final ActivityRecord r = (ActivityRecord) msg.obj;
2354                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2355                 if (needsVrMode) {
2356                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2357                             r.info.getComponentName(), false);
2358                 }
2359             } break;
2360             }
2361         }
2362     };
2363
2364     static final int COLLECT_PSS_BG_MSG = 1;
2365
2366     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2367         @Override
2368         public void handleMessage(Message msg) {
2369             switch (msg.what) {
2370             case COLLECT_PSS_BG_MSG: {
2371                 long start = SystemClock.uptimeMillis();
2372                 MemInfoReader memInfo = null;
2373                 synchronized (ActivityManagerService.this) {
2374                     if (mFullPssPending) {
2375                         mFullPssPending = false;
2376                         memInfo = new MemInfoReader();
2377                     }
2378                 }
2379                 if (memInfo != null) {
2380                     updateCpuStatsNow();
2381                     long nativeTotalPss = 0;
2382                     synchronized (mProcessCpuTracker) {
2383                         final int N = mProcessCpuTracker.countStats();
2384                         for (int j=0; j<N; j++) {
2385                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2386                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2387                                 // This is definitely an application process; skip it.
2388                                 continue;
2389                             }
2390                             synchronized (mPidsSelfLocked) {
2391                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2392                                     // This is one of our own processes; skip it.
2393                                     continue;
2394                                 }
2395                             }
2396                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2397                         }
2398                     }
2399                     memInfo.readMemInfo();
2400                     synchronized (ActivityManagerService.this) {
2401                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2402                                 + (SystemClock.uptimeMillis()-start) + "ms");
2403                         final long cachedKb = memInfo.getCachedSizeKb();
2404                         final long freeKb = memInfo.getFreeSizeKb();
2405                         final long zramKb = memInfo.getZramTotalSizeKb();
2406                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2407                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2408                                 kernelKb*1024, nativeTotalPss*1024);
2409                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2410                                 nativeTotalPss);
2411                     }
2412                 }
2413
2414                 int num = 0;
2415                 long[] tmp = new long[2];
2416                 do {
2417                     ProcessRecord proc;
2418                     int procState;
2419                     int pid;
2420                     long lastPssTime;
2421                     synchronized (ActivityManagerService.this) {
2422                         if (mPendingPssProcesses.size() <= 0) {
2423                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2424                                     "Collected PSS of " + num + " processes in "
2425                                     + (SystemClock.uptimeMillis() - start) + "ms");
2426                             mPendingPssProcesses.clear();
2427                             return;
2428                         }
2429                         proc = mPendingPssProcesses.remove(0);
2430                         procState = proc.pssProcState;
2431                         lastPssTime = proc.lastPssTime;
2432                         if (proc.thread != null && procState == proc.setProcState
2433                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2434                                         < SystemClock.uptimeMillis()) {
2435                             pid = proc.pid;
2436                         } else {
2437                             proc = null;
2438                             pid = 0;
2439                         }
2440                     }
2441                     if (proc != null) {
2442                         long pss = Debug.getPss(pid, tmp, null);
2443                         synchronized (ActivityManagerService.this) {
2444                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2445                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2446                                 num++;
2447                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2448                                         SystemClock.uptimeMillis());
2449                             }
2450                         }
2451                     }
2452                 } while (true);
2453             }
2454             }
2455         }
2456     };
2457
2458     public void setSystemProcess() {
2459         try {
2460             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2461             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2462             ServiceManager.addService("meminfo", new MemBinder(this));
2463             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2464             ServiceManager.addService("dbinfo", new DbBinder(this));
2465             if (MONITOR_CPU_USAGE) {
2466                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2467             }
2468             ServiceManager.addService("permission", new PermissionController(this));
2469             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2470
2471             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2472                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2473             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2474
2475             synchronized (this) {
2476                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2477                 app.persistent = true;
2478                 app.pid = MY_PID;
2479                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2480                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2481                 synchronized (mPidsSelfLocked) {
2482                     mPidsSelfLocked.put(app.pid, app);
2483                 }
2484                 updateLruProcessLocked(app, false, null);
2485                 updateOomAdjLocked();
2486             }
2487         } catch (PackageManager.NameNotFoundException e) {
2488             throw new RuntimeException(
2489                     "Unable to find android system package", e);
2490         }
2491     }
2492
2493     public void setWindowManager(WindowManagerService wm) {
2494         mWindowManager = wm;
2495         mStackSupervisor.setWindowManager(wm);
2496         mActivityStarter.setWindowManager(wm);
2497     }
2498
2499     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2500         mUsageStatsService = usageStatsManager;
2501     }
2502
2503     public void startObservingNativeCrashes() {
2504         final NativeCrashListener ncl = new NativeCrashListener(this);
2505         ncl.start();
2506     }
2507
2508     public IAppOpsService getAppOpsService() {
2509         return mAppOpsService;
2510     }
2511
2512     static class MemBinder extends Binder {
2513         ActivityManagerService mActivityManagerService;
2514         MemBinder(ActivityManagerService activityManagerService) {
2515             mActivityManagerService = activityManagerService;
2516         }
2517
2518         @Override
2519         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2520             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2521                     != PackageManager.PERMISSION_GRANTED) {
2522                 pw.println("Permission Denial: can't dump meminfo from from pid="
2523                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2524                         + " without permission " + android.Manifest.permission.DUMP);
2525                 return;
2526             }
2527
2528             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2529         }
2530     }
2531
2532     static class GraphicsBinder extends Binder {
2533         ActivityManagerService mActivityManagerService;
2534         GraphicsBinder(ActivityManagerService activityManagerService) {
2535             mActivityManagerService = activityManagerService;
2536         }
2537
2538         @Override
2539         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2540             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2541                     != PackageManager.PERMISSION_GRANTED) {
2542                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2543                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2544                         + " without permission " + android.Manifest.permission.DUMP);
2545                 return;
2546             }
2547
2548             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2549         }
2550     }
2551
2552     static class DbBinder extends Binder {
2553         ActivityManagerService mActivityManagerService;
2554         DbBinder(ActivityManagerService activityManagerService) {
2555             mActivityManagerService = activityManagerService;
2556         }
2557
2558         @Override
2559         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2560             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2561                     != PackageManager.PERMISSION_GRANTED) {
2562                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2563                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2564                         + " without permission " + android.Manifest.permission.DUMP);
2565                 return;
2566             }
2567
2568             mActivityManagerService.dumpDbInfo(fd, pw, args);
2569         }
2570     }
2571
2572     static class CpuBinder extends Binder {
2573         ActivityManagerService mActivityManagerService;
2574         CpuBinder(ActivityManagerService activityManagerService) {
2575             mActivityManagerService = activityManagerService;
2576         }
2577
2578         @Override
2579         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2580             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2581                     != PackageManager.PERMISSION_GRANTED) {
2582                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2583                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2584                         + " without permission " + android.Manifest.permission.DUMP);
2585                 return;
2586             }
2587
2588             synchronized (mActivityManagerService.mProcessCpuTracker) {
2589                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2590                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2591                         SystemClock.uptimeMillis()));
2592             }
2593         }
2594     }
2595
2596     public static final class Lifecycle extends SystemService {
2597         private final ActivityManagerService mService;
2598
2599         public Lifecycle(Context context) {
2600             super(context);
2601             mService = new ActivityManagerService(context);
2602         }
2603
2604         @Override
2605         public void onStart() {
2606             mService.start();
2607         }
2608
2609         public ActivityManagerService getService() {
2610             return mService;
2611         }
2612     }
2613
2614     // Note: This method is invoked on the main thread but may need to attach various
2615     // handlers to other threads.  So take care to be explicit about the looper.
2616     public ActivityManagerService(Context systemContext) {
2617         mContext = systemContext;
2618         mFactoryTest = FactoryTest.getMode();
2619         mSystemThread = ActivityThread.currentActivityThread();
2620
2621         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2622
2623         mHandlerThread = new ServiceThread(TAG,
2624                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2625         mHandlerThread.start();
2626         mHandler = new MainHandler(mHandlerThread.getLooper());
2627         mUiHandler = new UiHandler();
2628
2629         /* static; one-time init here */
2630         if (sKillHandler == null) {
2631             sKillThread = new ServiceThread(TAG + ":kill",
2632                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2633             sKillThread.start();
2634             sKillHandler = new KillHandler(sKillThread.getLooper());
2635         }
2636
2637         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2638                 "foreground", BROADCAST_FG_TIMEOUT, false);
2639         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2640                 "background", BROADCAST_BG_TIMEOUT, true);
2641         mBroadcastQueues[0] = mFgBroadcastQueue;
2642         mBroadcastQueues[1] = mBgBroadcastQueue;
2643
2644         mServices = new ActiveServices(this);
2645         mProviderMap = new ProviderMap(this);
2646         mAppErrors = new AppErrors(mContext, this);
2647
2648         // TODO: Move creation of battery stats service outside of activity manager service.
2649         File dataDir = Environment.getDataDirectory();
2650         File systemDir = new File(dataDir, "system");
2651         systemDir.mkdirs();
2652         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2653         mBatteryStatsService.getActiveStatistics().readLocked();
2654         mBatteryStatsService.scheduleWriteToDisk();
2655         mOnBattery = DEBUG_POWER ? true
2656                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2657         mBatteryStatsService.getActiveStatistics().setCallback(this);
2658
2659         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2660
2661         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2662         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2663                 new IAppOpsCallback.Stub() {
2664                     @Override public void opChanged(int op, int uid, String packageName) {
2665                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2666                             if (mAppOpsService.checkOperation(op, uid, packageName)
2667                                     != AppOpsManager.MODE_ALLOWED) {
2668                                 runInBackgroundDisabled(uid);
2669                             }
2670                         }
2671                     }
2672                 });
2673
2674         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2675
2676         mUserController = new UserController(this);
2677
2678         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2679             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2680
2681         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2682             mUseFifoUiScheduling = true;
2683         }
2684
2685         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2686
2687         mConfiguration.setToDefaults();
2688         mConfiguration.setLocales(LocaleList.getDefault());
2689
2690         mConfigurationSeq = mConfiguration.seq = 1;
2691         mProcessCpuTracker.init();
2692
2693         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2694         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2695         mStackSupervisor = new ActivityStackSupervisor(this);
2696         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2697         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2698
2699         mProcessCpuThread = new Thread("CpuTracker") {
2700             @Override
2701             public void run() {
2702                 while (true) {
2703                     try {
2704                         try {
2705                             synchronized(this) {
2706                                 final long now = SystemClock.uptimeMillis();
2707                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2708                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2709                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2710                                 //        + ", write delay=" + nextWriteDelay);
2711                                 if (nextWriteDelay < nextCpuDelay) {
2712                                     nextCpuDelay = nextWriteDelay;
2713                                 }
2714                                 if (nextCpuDelay > 0) {
2715                                     mProcessCpuMutexFree.set(true);
2716                                     this.wait(nextCpuDelay);
2717                                 }
2718                             }
2719                         } catch (InterruptedException e) {
2720                         }
2721                         updateCpuStatsNow();
2722                     } catch (Exception e) {
2723                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2724                     }
2725                 }
2726             }
2727         };
2728
2729         Watchdog.getInstance().addMonitor(this);
2730         Watchdog.getInstance().addThread(mHandler);
2731     }
2732
2733     public void setSystemServiceManager(SystemServiceManager mgr) {
2734         mSystemServiceManager = mgr;
2735     }
2736
2737     public void setInstaller(Installer installer) {
2738         mInstaller = installer;
2739     }
2740
2741     private void start() {
2742         Process.removeAllProcessGroups();
2743         mProcessCpuThread.start();
2744
2745         mBatteryStatsService.publish(mContext);
2746         mAppOpsService.publish(mContext);
2747         Slog.d("AppOps", "AppOpsService published");
2748         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2749     }
2750
2751     void onUserStoppedLocked(int userId) {
2752         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2753     }
2754
2755     public void initPowerManagement() {
2756         mStackSupervisor.initPowerManagement();
2757         mBatteryStatsService.initPowerManagement();
2758         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2759         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2760         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2761         mVoiceWakeLock.setReferenceCounted(false);
2762     }
2763
2764     @Override
2765     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2766             throws RemoteException {
2767         if (code == SYSPROPS_TRANSACTION) {
2768             // We need to tell all apps about the system property change.
2769             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2770             synchronized(this) {
2771                 final int NP = mProcessNames.getMap().size();
2772                 for (int ip=0; ip<NP; ip++) {
2773                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2774                     final int NA = apps.size();
2775                     for (int ia=0; ia<NA; ia++) {
2776                         ProcessRecord app = apps.valueAt(ia);
2777                         if (app.thread != null) {
2778                             procs.add(app.thread.asBinder());
2779                         }
2780                     }
2781                 }
2782             }
2783
2784             int N = procs.size();
2785             for (int i=0; i<N; i++) {
2786                 Parcel data2 = Parcel.obtain();
2787                 try {
2788                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2789                 } catch (RemoteException e) {
2790                 }
2791                 data2.recycle();
2792             }
2793         }
2794         try {
2795             return super.onTransact(code, data, reply, flags);
2796         } catch (RuntimeException e) {
2797             // The activity manager only throws security exceptions, so let's
2798             // log all others.
2799             if (!(e instanceof SecurityException)) {
2800                 Slog.wtf(TAG, "Activity Manager Crash", e);
2801             }
2802             throw e;
2803         }
2804     }
2805
2806     void updateCpuStats() {
2807         final long now = SystemClock.uptimeMillis();
2808         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2809             return;
2810         }
2811         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2812             synchronized (mProcessCpuThread) {
2813                 mProcessCpuThread.notify();
2814             }
2815         }
2816     }
2817
2818     void updateCpuStatsNow() {
2819         synchronized (mProcessCpuTracker) {
2820             mProcessCpuMutexFree.set(false);
2821             final long now = SystemClock.uptimeMillis();
2822             boolean haveNewCpuStats = false;
2823
2824             if (MONITOR_CPU_USAGE &&
2825                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2826                 mLastCpuTime.set(now);
2827                 mProcessCpuTracker.update();
2828                 if (mProcessCpuTracker.hasGoodLastStats()) {
2829                     haveNewCpuStats = true;
2830                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2831                     //Slog.i(TAG, "Total CPU usage: "
2832                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2833
2834                     // Slog the cpu usage if the property is set.
2835                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2836                         int user = mProcessCpuTracker.getLastUserTime();
2837                         int system = mProcessCpuTracker.getLastSystemTime();
2838                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2839                         int irq = mProcessCpuTracker.getLastIrqTime();
2840                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2841                         int idle = mProcessCpuTracker.getLastIdleTime();
2842
2843                         int total = user + system + iowait + irq + softIrq + idle;
2844                         if (total == 0) total = 1;
2845
2846                         EventLog.writeEvent(EventLogTags.CPU,
2847                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2848                                 (user * 100) / total,
2849                                 (system * 100) / total,
2850                                 (iowait * 100) / total,
2851                                 (irq * 100) / total,
2852                                 (softIrq * 100) / total);
2853                     }
2854                 }
2855             }
2856
2857             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2858             synchronized(bstats) {
2859                 synchronized(mPidsSelfLocked) {
2860                     if (haveNewCpuStats) {
2861                         if (bstats.startAddingCpuLocked()) {
2862                             int totalUTime = 0;
2863                             int totalSTime = 0;
2864                             final int N = mProcessCpuTracker.countStats();
2865                             for (int i=0; i<N; i++) {
2866                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2867                                 if (!st.working) {
2868                                     continue;
2869                                 }
2870                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2871                                 totalUTime += st.rel_utime;
2872                                 totalSTime += st.rel_stime;
2873                                 if (pr != null) {
2874                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2875                                     if (ps == null || !ps.isActive()) {
2876                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2877                                                 pr.info.uid, pr.processName);
2878                                     }
2879                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2880                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2881                                 } else {
2882                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2883                                     if (ps == null || !ps.isActive()) {
2884                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2885                                                 bstats.mapUid(st.uid), st.name);
2886                                     }
2887                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888                                 }
2889                             }
2890                             final int userTime = mProcessCpuTracker.getLastUserTime();
2891                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2892                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2893                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2894                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2895                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2896                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2897                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2898                         }
2899                     }
2900                 }
2901
2902                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2903                     mLastWriteTime = now;
2904                     mBatteryStatsService.scheduleWriteToDisk();
2905                 }
2906             }
2907         }
2908     }
2909
2910     @Override
2911     public void batteryNeedsCpuUpdate() {
2912         updateCpuStatsNow();
2913     }
2914
2915     @Override
2916     public void batteryPowerChanged(boolean onBattery) {
2917         // When plugging in, update the CPU stats first before changing
2918         // the plug state.
2919         updateCpuStatsNow();
2920         synchronized (this) {
2921             synchronized(mPidsSelfLocked) {
2922                 mOnBattery = DEBUG_POWER ? true : onBattery;
2923             }
2924         }
2925     }
2926
2927     @Override
2928     public void batterySendBroadcast(Intent intent) {
2929         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2930                 AppOpsManager.OP_NONE, null, false, false,
2931                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2932     }
2933
2934     /**
2935      * Initialize the application bind args. These are passed to each
2936      * process when the bindApplication() IPC is sent to the process. They're
2937      * lazily setup to make sure the services are running when they're asked for.
2938      */
2939     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2940         // Isolated processes won't get this optimization, so that we don't
2941         // violate the rules about which services they have access to.
2942         if (isolated) {
2943             if (mIsolatedAppBindArgs == null) {
2944                 mIsolatedAppBindArgs = new HashMap<>();
2945                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2946             }
2947             return mIsolatedAppBindArgs;
2948         }
2949
2950         if (mAppBindArgs == null) {
2951             mAppBindArgs = new HashMap<>();
2952
2953             // Setup the application init args
2954             mAppBindArgs.put("package", ServiceManager.getService("package"));
2955             mAppBindArgs.put("window", ServiceManager.getService("window"));
2956             mAppBindArgs.put(Context.ALARM_SERVICE,
2957                     ServiceManager.getService(Context.ALARM_SERVICE));
2958         }
2959         return mAppBindArgs;
2960     }
2961
2962     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2963         if (r == null || mFocusedActivity == r) {
2964             return false;
2965         }
2966
2967         if (!r.isFocusable()) {
2968             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2969             return false;
2970         }
2971
2972         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2973
2974         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2975         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2976                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2977         mDoingSetFocusedActivity = true;
2978
2979         final ActivityRecord last = mFocusedActivity;
2980         mFocusedActivity = r;
2981         if (r.task.isApplicationTask()) {
2982             if (mCurAppTimeTracker != r.appTimeTracker) {
2983                 // We are switching app tracking.  Complete the current one.
2984                 if (mCurAppTimeTracker != null) {
2985                     mCurAppTimeTracker.stop();
2986                     mHandler.obtainMessage(
2987                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2988                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2989                     mCurAppTimeTracker = null;
2990                 }
2991                 if (r.appTimeTracker != null) {
2992                     mCurAppTimeTracker = r.appTimeTracker;
2993                     startTimeTrackingFocusedActivityLocked();
2994                 }
2995             } else {
2996                 startTimeTrackingFocusedActivityLocked();
2997             }
2998         } else {
2999             r.appTimeTracker = null;
3000         }
3001         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3002         // TODO: Probably not, because we don't want to resume voice on switching
3003         // back to this activity
3004         if (r.task.voiceInteractor != null) {
3005             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3006         } else {
3007             finishRunningVoiceLocked();
3008             IVoiceInteractionSession session;
3009             if (last != null && ((session = last.task.voiceSession) != null
3010                     || (session = last.voiceSession) != null)) {
3011                 // We had been in a voice interaction session, but now focused has
3012                 // move to something different.  Just finish the session, we can't
3013                 // return to it and retain the proper state and synchronization with
3014                 // the voice interaction service.
3015                 finishVoiceTask(session);
3016             }
3017         }
3018         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3019             mWindowManager.setFocusedApp(r.appToken, true);
3020         }
3021         applyUpdateLockStateLocked(r);
3022         applyUpdateVrModeLocked(r);
3023         if (mFocusedActivity.userId != mLastFocusedUserId) {
3024             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3025             mHandler.obtainMessage(
3026                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3027             mLastFocusedUserId = mFocusedActivity.userId;
3028         }
3029
3030         // Log a warning if the focused app is changed during the process. This could
3031         // indicate a problem of the focus setting logic!
3032         if (mFocusedActivity != r) Slog.w(TAG,
3033                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3034         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3035
3036         EventLogTags.writeAmFocusedActivity(
3037                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3038                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3039                 reason);
3040         return true;
3041     }
3042
3043     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3044         if (mFocusedActivity != goingAway) {
3045             return;
3046         }
3047
3048         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3049         if (focusedStack != null) {
3050             final ActivityRecord top = focusedStack.topActivity();
3051             if (top != null && top.userId != mLastFocusedUserId) {
3052                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3053                 mHandler.sendMessage(
3054                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3055                 mLastFocusedUserId = top.userId;
3056             }
3057         }
3058
3059         // Try to move focus to another activity if possible.
3060         if (setFocusedActivityLocked(
3061                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3062             return;
3063         }
3064
3065         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3066                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3067         mFocusedActivity = null;
3068         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3069     }
3070
3071     @Override
3072     public void setFocusedStack(int stackId) {
3073         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3074         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3075         final long callingId = Binder.clearCallingIdentity();
3076         try {
3077             synchronized (this) {
3078                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3079                 if (stack == null) {
3080                     return;
3081                 }
3082                 final ActivityRecord r = stack.topRunningActivityLocked();
3083                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3084                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3085                 }
3086             }
3087         } finally {
3088             Binder.restoreCallingIdentity(callingId);
3089         }
3090     }
3091
3092     @Override
3093     public void setFocusedTask(int taskId) {
3094         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3095         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3096         final long callingId = Binder.clearCallingIdentity();
3097         try {
3098             synchronized (this) {
3099                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3100                 if (task == null) {
3101                     return;
3102                 }
3103                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3104                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3105                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3106                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3107                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3108                                 "setFocusedTask", ANIMATE);
3109                     }
3110                     return;
3111                 }
3112                 final ActivityRecord r = task.topRunningActivityLocked();
3113                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3114                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3115                 }
3116             }
3117         } finally {
3118             Binder.restoreCallingIdentity(callingId);
3119         }
3120     }
3121
3122     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3123     @Override
3124     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3125         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3126         synchronized (this) {
3127             if (listener != null) {
3128                 mTaskStackListeners.register(listener);
3129             }
3130         }
3131     }
3132
3133     @Override
3134     public void notifyActivityDrawn(IBinder token) {
3135         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3136         synchronized (this) {
3137             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3138             if (r != null) {
3139                 r.task.stack.notifyActivityDrawnLocked(r);
3140             }
3141         }
3142     }
3143
3144     final void applyUpdateLockStateLocked(ActivityRecord r) {
3145         // Modifications to the UpdateLock state are done on our handler, outside
3146         // the activity manager's locks.  The new state is determined based on the
3147         // state *now* of the relevant activity record.  The object is passed to
3148         // the handler solely for logging detail, not to be consulted/modified.
3149         final boolean nextState = r != null && r.immersive;
3150         mHandler.sendMessage(
3151                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3152     }
3153
3154     final void applyUpdateVrModeLocked(ActivityRecord r) {
3155         mHandler.sendMessage(
3156                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3157     }
3158
3159     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3160         mHandler.sendMessage(
3161                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3162     }
3163
3164     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3165             ComponentName callingPackage, boolean immediate) {
3166         VrManagerInternal vrService =
3167                 LocalServices.getService(VrManagerInternal.class);
3168         if (immediate) {
3169             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3170         } else {
3171             vrService.setVrMode(enabled, packageName, userId, callingPackage);
3172         }
3173     }
3174
3175     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3176         Message msg = Message.obtain();
3177         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3178         msg.obj = r.task.askedCompatMode ? null : r;
3179         mUiHandler.sendMessage(msg);
3180     }
3181
3182     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3183         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3184                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3185             final Message msg = Message.obtain();
3186             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3187             msg.obj = r;
3188             mUiHandler.sendMessage(msg);
3189         }
3190     }
3191
3192     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3193             String what, Object obj, ProcessRecord srcApp) {
3194         app.lastActivityTime = now;
3195
3196         if (app.activities.size() > 0) {
3197             // Don't want to touch dependent processes that are hosting activities.
3198             return index;
3199         }
3200
3201         int lrui = mLruProcesses.lastIndexOf(app);
3202         if (lrui < 0) {
3203             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3204                     + what + " " + obj + " from " + srcApp);
3205             return index;
3206         }
3207
3208         if (lrui >= index) {
3209             // Don't want to cause this to move dependent processes *back* in the
3210             // list as if they were less frequently used.
3211             return index;
3212         }
3213
3214         if (lrui >= mLruProcessActivityStart) {
3215             // Don't want to touch dependent processes that are hosting activities.
3216             return index;
3217         }
3218
3219         mLruProcesses.remove(lrui);
3220         if (index > 0) {
3221             index--;
3222         }
3223         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3224                 + " in LRU list: " + app);
3225         mLruProcesses.add(index, app);
3226         return index;
3227     }
3228
3229     static void killProcessGroup(int uid, int pid) {
3230         if (sKillHandler != null) {
3231             sKillHandler.sendMessage(
3232                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3233         } else {
3234             Slog.w(TAG, "Asked to kill process group before system bringup!");
3235             Process.killProcessGroup(uid, pid);
3236         }
3237     }
3238
3239     final void removeLruProcessLocked(ProcessRecord app) {
3240         int lrui = mLruProcesses.lastIndexOf(app);
3241         if (lrui >= 0) {
3242             if (!app.killed) {
3243                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3244                 Process.killProcessQuiet(app.pid);
3245                 killProcessGroup(app.uid, app.pid);
3246             }
3247             if (lrui <= mLruProcessActivityStart) {
3248                 mLruProcessActivityStart--;
3249             }
3250             if (lrui <= mLruProcessServiceStart) {
3251                 mLruProcessServiceStart--;
3252             }
3253             mLruProcesses.remove(lrui);
3254         }
3255     }
3256
3257     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3258             ProcessRecord client) {
3259         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3260                 || app.treatLikeActivity;
3261         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3262         if (!activityChange && hasActivity) {
3263             // The process has activities, so we are only allowing activity-based adjustments
3264             // to move it.  It should be kept in the front of the list with other
3265             // processes that have activities, and we don't want those to change their
3266             // order except due to activity operations.
3267             return;
3268         }
3269
3270         mLruSeq++;
3271         final long now = SystemClock.uptimeMillis();
3272         app.lastActivityTime = now;
3273
3274         // First a quick reject: if the app is already at the position we will
3275         // put it, then there is nothing to do.
3276         if (hasActivity) {
3277             final int N = mLruProcesses.size();
3278             if (N > 0 && mLruProcesses.get(N-1) == app) {
3279                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3280                 return;
3281             }
3282         } else {
3283             if (mLruProcessServiceStart > 0
3284                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3285                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3286                 return;
3287             }
3288         }
3289
3290         int lrui = mLruProcesses.lastIndexOf(app);
3291
3292         if (app.persistent && lrui >= 0) {
3293             // We don't care about the position of persistent processes, as long as
3294             // they are in the list.
3295             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3296             return;
3297         }
3298
3299         /* In progress: compute new position first, so we can avoid doing work
3300            if the process is not actually going to move.  Not yet working.
3301         int addIndex;
3302         int nextIndex;
3303         boolean inActivity = false, inService = false;
3304         if (hasActivity) {
3305             // Process has activities, put it at the very tipsy-top.
3306             addIndex = mLruProcesses.size();
3307             nextIndex = mLruProcessServiceStart;
3308             inActivity = true;
3309         } else if (hasService) {
3310             // Process has services, put it at the top of the service list.
3311             addIndex = mLruProcessActivityStart;
3312             nextIndex = mLruProcessServiceStart;
3313             inActivity = true;
3314             inService = true;
3315         } else  {
3316             // Process not otherwise of interest, it goes to the top of the non-service area.
3317             addIndex = mLruProcessServiceStart;
3318             if (client != null) {
3319                 int clientIndex = mLruProcesses.lastIndexOf(client);
3320                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3321                         + app);
3322                 if (clientIndex >= 0 && addIndex > clientIndex) {
3323                     addIndex = clientIndex;
3324                 }
3325             }
3326             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3327         }
3328
3329         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3330                 + mLruProcessActivityStart + "): " + app);
3331         */
3332
3333         if (lrui >= 0) {
3334             if (lrui < mLruProcessActivityStart) {
3335                 mLruProcessActivityStart--;
3336             }
3337             if (lrui < mLruProcessServiceStart) {
3338                 mLruProcessServiceStart--;
3339             }
3340             /*
3341             if (addIndex > lrui) {
3342                 addIndex--;
3343             }
3344             if (nextIndex > lrui) {
3345                 nextIndex--;
3346             }
3347             */
3348             mLruProcesses.remove(lrui);
3349         }
3350
3351         /*
3352         mLruProcesses.add(addIndex, app);
3353         if (inActivity) {
3354             mLruProcessActivityStart++;
3355         }
3356         if (inService) {
3357             mLruProcessActivityStart++;
3358         }
3359         */
3360
3361         int nextIndex;
3362         if (hasActivity) {
3363             final int N = mLruProcesses.size();
3364             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3365                 // Process doesn't have activities, but has clients with
3366                 // activities...  move it up, but one below the top (the top
3367                 // should always have a real activity).
3368                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3369                         "Adding to second-top of LRU activity list: " + app);
3370                 mLruProcesses.add(N - 1, app);
3371                 // To keep it from spamming the LRU list (by making a bunch of clients),
3372                 // we will push down any other entries owned by the app.
3373                 final int uid = app.info.uid;
3374                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3375                     ProcessRecord subProc = mLruProcesses.get(i);
3376                     if (subProc.info.uid == uid) {
3377                         // We want to push this one down the list.  If the process after
3378                         // it is for the same uid, however, don't do so, because we don't
3379                         // want them internally to be re-ordered.
3380                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3381                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3382                                     "Pushing uid " + uid + " swapping at " + i + ": "
3383                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3384                             ProcessRecord tmp = mLruProcesses.get(i);
3385                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3386                             mLruProcesses.set(i - 1, tmp);
3387                             i--;
3388                         }
3389                     } else {
3390                         // A gap, we can stop here.
3391                         break;
3392                     }
3393                 }
3394             } else {
3395                 // Process has activities, put it at the very tipsy-top.
3396                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3397                 mLruProcesses.add(app);
3398             }
3399             nextIndex = mLruProcessServiceStart;
3400         } else if (hasService) {
3401             // Process has services, put it at the top of the service list.
3402             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3403             mLruProcesses.add(mLruProcessActivityStart, app);
3404             nextIndex = mLruProcessServiceStart;
3405             mLruProcessActivityStart++;
3406         } else  {
3407             // Process not otherwise of interest, it goes to the top of the non-service area.
3408             int index = mLruProcessServiceStart;
3409             if (client != null) {
3410                 // If there is a client, don't allow the process to be moved up higher
3411                 // in the list than that client.
3412                 int clientIndex = mLruProcesses.lastIndexOf(client);
3413                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3414                         + " when updating " + app);
3415                 if (clientIndex <= lrui) {
3416                     // Don't allow the client index restriction to push it down farther in the
3417                     // list than it already is.
3418                     clientIndex = lrui;
3419                 }
3420                 if (clientIndex >= 0 && index > clientIndex) {
3421                     index = clientIndex;
3422                 }
3423             }
3424             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3425             mLruProcesses.add(index, app);
3426             nextIndex = index-1;
3427             mLruProcessActivityStart++;
3428             mLruProcessServiceStart++;
3429         }
3430
3431         // If the app is currently using a content provider or service,
3432         // bump those processes as well.
3433         for (int j=app.connections.size()-1; j>=0; j--) {
3434             ConnectionRecord cr = app.connections.valueAt(j);
3435             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3436                     && cr.binding.service.app != null
3437                     && cr.binding.service.app.lruSeq != mLruSeq
3438                     && !cr.binding.service.app.persistent) {
3439                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3440                         "service connection", cr, app);
3441             }
3442         }
3443         for (int j=app.conProviders.size()-1; j>=0; j--) {
3444             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3445             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3446                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3447                         "provider reference", cpr, app);
3448             }
3449         }
3450     }
3451
3452     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3453         if (uid == Process.SYSTEM_UID) {
3454             // The system gets to run in any process.  If there are multiple
3455             // processes with the same uid, just pick the first (this
3456             // should never happen).
3457             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3458             if (procs == null) return null;
3459             final int procCount = procs.size();
3460             for (int i = 0; i < procCount; i++) {
3461                 final int procUid = procs.keyAt(i);
3462                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3463                     // Don't use an app process or different user process for system component.
3464                     continue;
3465                 }
3466                 return procs.valueAt(i);
3467             }
3468         }
3469         ProcessRecord proc = mProcessNames.get(processName, uid);
3470         if (false && proc != null && !keepIfLarge
3471                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3472                 && proc.lastCachedPss >= 4000) {
3473             // Turn this condition on to cause killing to happen regularly, for testing.
3474             if (proc.baseProcessTracker != null) {
3475                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3476             }
3477             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3478         } else if (proc != null && !keepIfLarge
3479                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3480                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3481             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3482             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3483                 if (proc.baseProcessTracker != null) {
3484                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485                 }
3486                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3487             }
3488         }
3489         return proc;
3490     }
3491
3492     void notifyPackageUse(String packageName, int reason) {
3493         IPackageManager pm = AppGlobals.getPackageManager();
3494         try {
3495             pm.notifyPackageUse(packageName, reason);
3496         } catch (RemoteException e) {
3497         }
3498     }
3499
3500     boolean isNextTransitionForward() {
3501         int transit = mWindowManager.getPendingAppTransition();
3502         return transit == TRANSIT_ACTIVITY_OPEN
3503                 || transit == TRANSIT_TASK_OPEN
3504                 || transit == TRANSIT_TASK_TO_FRONT;
3505     }
3506
3507     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3508             String processName, String abiOverride, int uid, Runnable crashHandler) {
3509         synchronized(this) {
3510             ApplicationInfo info = new ApplicationInfo();
3511             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3512             // For isolated processes, the former contains the parent's uid and the latter the
3513             // actual uid of the isolated process.
3514             // In the special case introduced by this method (which is, starting an isolated
3515             // process directly from the SystemServer without an actual parent app process) the
3516             // closest thing to a parent's uid is SYSTEM_UID.
3517             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3518             // the |isolated| logic in the ProcessRecord constructor.
3519             info.uid = Process.SYSTEM_UID;
3520             info.processName = processName;
3521             info.className = entryPoint;
3522             info.packageName = "android";
3523             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3524                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3525                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3526                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3527                     crashHandler);
3528             return proc != null ? proc.pid : 0;
3529         }
3530     }
3531
3532     final ProcessRecord startProcessLocked(String processName,
3533             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3534             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3535             boolean isolated, boolean keepIfLarge) {
3536         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3537                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3538                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3539                 null /* crashHandler */);
3540     }
3541
3542     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3543             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3544             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3545             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3546         long startTime = SystemClock.elapsedRealtime();
3547         ProcessRecord app;
3548         if (!isolated) {
3549             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3550             checkTime(startTime, "startProcess: after getProcessRecord");
3551
3552             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3553                 // If we are in the background, then check to see if this process
3554                 // is bad.  If so, we will just silently fail.
3555                 if (mAppErrors.isBadProcessLocked(info)) {
3556                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3557                             + "/" + info.processName);
3558                     return null;
3559                 }
3560             } else {
3561                 // When the user is explicitly starting a process, then clear its
3562                 // crash count so that we won't make it bad until they see at
3563                 // least one crash dialog again, and make the process good again
3564                 // if it had been bad.
3565                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3566                         + "/" + info.processName);
3567                 mAppErrors.resetProcessCrashTimeLocked(info);
3568                 if (mAppErrors.isBadProcessLocked(info)) {
3569                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3570                             UserHandle.getUserId(info.uid), info.uid,
3571                             info.processName);
3572                     mAppErrors.clearBadProcessLocked(info);
3573                     if (app != null) {
3574                         app.bad = false;
3575                     }
3576                 }
3577             }
3578         } else {
3579             // If this is an isolated process, it can't re-use an existing process.
3580             app = null;
3581         }
3582
3583         // app launch boost for big.little configurations
3584         // use cpusets to migrate freshly launched tasks to big cores
3585         nativeMigrateToBoost();
3586         mIsBoosted = true;
3587         mBoostStartTime = SystemClock.uptimeMillis();
3588         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3589         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3590
3591         // We don't have to do anything more if:
3592         // (1) There is an existing application record; and
3593         // (2) The caller doesn't think it is dead, OR there is no thread
3594         //     object attached to it so we know it couldn't have crashed; and
3595         // (3) There is a pid assigned to it, so it is either starting or
3596         //     already running.
3597         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3598                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3599                 + " thread=" + (app != null ? app.thread : null)
3600                 + " pid=" + (app != null ? app.pid : -1));
3601         if (app != null && app.pid > 0) {
3602             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3603                 // We already have the app running, or are waiting for it to
3604                 // come up (we have a pid but not yet its thread), so keep it.
3605                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3606                 // If this is a new package in the process, add the package to the list
3607                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3608                 checkTime(startTime, "startProcess: done, added package to proc");
3609                 return app;
3610             }
3611
3612             // An application record is attached to a previous process,
3613             // clean it up now.
3614             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3615             checkTime(startTime, "startProcess: bad proc running, killing");
3616             killProcessGroup(app.uid, app.pid);
3617             handleAppDiedLocked(app, true, true);
3618             checkTime(startTime, "startProcess: done killing old proc");
3619         }
3620
3621         String hostingNameStr = hostingName != null
3622                 ? hostingName.flattenToShortString() : null;
3623
3624         if (app == null) {
3625             checkTime(startTime, "startProcess: creating new process record");
3626             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3627             if (app == null) {
3628                 Slog.w(TAG, "Failed making new process record for "
3629                         + processName + "/" + info.uid + " isolated=" + isolated);
3630                 return null;
3631             }
3632             app.crashHandler = crashHandler;
3633             checkTime(startTime, "startProcess: done creating new process record");
3634         } else {
3635             // If this is a new package in the process, add the package to the list
3636             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3637             checkTime(startTime, "startProcess: added package to existing proc");
3638         }
3639
3640         // If the system is not ready yet, then hold off on starting this
3641         // process until it is.
3642         if (!mProcessesReady
3643                 && !isAllowedWhileBooting(info)
3644                 && !allowWhileBooting) {
3645             if (!mProcessesOnHold.contains(app)) {
3646                 mProcessesOnHold.add(app);
3647             }
3648             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3649                     "System not ready, putting on hold: " + app);
3650             checkTime(startTime, "startProcess: returning with proc on hold");
3651             return app;
3652         }
3653
3654         checkTime(startTime, "startProcess: stepping in to startProcess");
3655         startProcessLocked(
3656                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3657         checkTime(startTime, "startProcess: done starting proc!");
3658         return (app.pid != 0) ? app : null;
3659     }
3660
3661     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3662         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3663     }
3664
3665     private final void startProcessLocked(ProcessRecord app,
3666             String hostingType, String hostingNameStr) {
3667         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3668                 null /* entryPoint */, null /* entryPointArgs */);
3669     }
3670
3671     private final void startProcessLocked(ProcessRecord app, String hostingType,
3672             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3673         long startTime = SystemClock.elapsedRealtime();
3674         if (app.pid > 0 && app.pid != MY_PID) {
3675             checkTime(startTime, "startProcess: removing from pids map");
3676             synchronized (mPidsSelfLocked) {
3677                 mPidsSelfLocked.remove(app.pid);
3678                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3679             }
3680             checkTime(startTime, "startProcess: done removing from pids map");
3681             app.setPid(0);
3682         }
3683
3684         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3685                 "startProcessLocked removing on hold: " + app);
3686         mProcessesOnHold.remove(app);
3687
3688         checkTime(startTime, "startProcess: starting to update cpu stats");
3689         updateCpuStats();
3690         checkTime(startTime, "startProcess: done updating cpu stats");
3691
3692         try {
3693             try {
3694                 final int userId = UserHandle.getUserId(app.uid);
3695                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3696             } catch (RemoteException e) {
3697                 throw e.rethrowAsRuntimeException();
3698             }
3699
3700             int uid = app.uid;
3701             int[] gids = null;
3702             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3703             if (!app.isolated) {
3704                 int[] permGids = null;
3705                 try {
3706                     checkTime(startTime, "startProcess: getting gids from package manager");
3707                     final IPackageManager pm = AppGlobals.getPackageManager();
3708                     permGids = pm.getPackageGids(app.info.packageName,
3709                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3710                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3711                             MountServiceInternal.class);
3712                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3713                             app.info.packageName);
3714                 } catch (RemoteException e) {
3715                     throw e.rethrowAsRuntimeException();
3716                 }
3717
3718                 /*
3719                  * Add shared application and profile GIDs so applications can share some
3720                  * resources like shared libraries and access user-wide resources
3721                  */
3722                 if (ArrayUtils.isEmpty(permGids)) {
3723                     gids = new int[2];
3724                 } else {
3725                     gids = new int[permGids.length + 2];
3726                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3727                 }
3728                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3729                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3730             }
3731             checkTime(startTime, "startProcess: building args");
3732             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3733                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3734                         && mTopComponent != null
3735                         && app.processName.equals(mTopComponent.getPackageName())) {
3736                     uid = 0;
3737                 }
3738                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3739                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3740                     uid = 0;
3741                 }
3742             }
3743             int debugFlags = 0;
3744             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3745                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3746                 // Also turn on CheckJNI for debuggable apps. It's quite
3747                 // awkward to turn on otherwise.
3748                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3749             }
3750             // Run the app in safe mode if its manifest requests so or the
3751             // system is booted in safe mode.
3752             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3753                 mSafeMode == true) {
3754                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3755             }
3756             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3757                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3758             }
3759             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3760             if ("true".equals(genDebugInfoProperty)) {
3761                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3762             }
3763             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3764                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3765             }
3766             if ("1".equals(SystemProperties.get("debug.assert"))) {
3767                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3768             }
3769             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3770                 // Enable all debug flags required by the native debugger.
3771                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3772                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3773                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3774                 mNativeDebuggingApp = null;
3775             }
3776
3777             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3778             if (requiredAbi == null) {
3779                 requiredAbi = Build.SUPPORTED_ABIS[0];
3780             }
3781
3782             String instructionSet = null;
3783             if (app.info.primaryCpuAbi != null) {
3784                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3785             }
3786
3787             app.gids = gids;
3788             app.requiredAbi = requiredAbi;
3789             app.instructionSet = instructionSet;
3790
3791             // Start the process.  It will either succeed and return a result containing
3792             // the PID of the new process, or else throw a RuntimeException.
3793             boolean isActivityProcess = (entryPoint == null);
3794             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3795             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3796                     app.processName);
3797             checkTime(startTime, "startProcess: asking zygote to start proc");
3798             Process.ProcessStartResult startResult = Process.start(entryPoint,
3799                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3800                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3801                     app.info.dataDir, entryPointArgs);
3802             checkTime(startTime, "startProcess: returned from zygote!");
3803             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3804
3805             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3806             checkTime(startTime, "startProcess: done updating battery stats");
3807
3808             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3809                     UserHandle.getUserId(uid), startResult.pid, uid,
3810                     app.processName, hostingType,
3811                     hostingNameStr != null ? hostingNameStr : "");
3812
3813             try {
3814                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3815                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3816             } catch (RemoteException ex) {
3817                 // Ignore
3818             }
3819
3820             if (app.persistent) {
3821                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3822             }
3823
3824             checkTime(startTime, "startProcess: building log message");
3825             StringBuilder buf = mStringBuilder;
3826             buf.setLength(0);
3827             buf.append("Start proc ");
3828             buf.append(startResult.pid);
3829             buf.append(':');
3830             buf.append(app.processName);
3831             buf.append('/');
3832             UserHandle.formatUid(buf, uid);
3833             if (!isActivityProcess) {
3834                 buf.append(" [");
3835                 buf.append(entryPoint);
3836                 buf.append("]");
3837             }
3838             buf.append(" for ");
3839             buf.append(hostingType);
3840             if (hostingNameStr != null) {
3841                 buf.append(" ");
3842                 buf.append(hostingNameStr);
3843             }
3844             Slog.i(TAG, buf.toString());
3845             app.setPid(startResult.pid);
3846             app.usingWrapper = startResult.usingWrapper;
3847             app.removed = false;
3848             app.killed = false;
3849             app.killedByAm = false;
3850             checkTime(startTime, "startProcess: starting to update pids map");
3851             ProcessRecord oldApp;
3852             synchronized (mPidsSelfLocked) {
3853                 oldApp = mPidsSelfLocked.get(startResult.pid);
3854             }
3855             // If there is already an app occupying that pid that hasn't been cleaned up
3856             if (oldApp != null && !app.isolated) {
3857                 // Clean up anything relating to this pid first
3858                 Slog.w(TAG, "Reusing pid " + startResult.pid
3859                         + " while app is still mapped to it");
3860                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3861                         true /*replacingPid*/);
3862             }
3863             synchronized (mPidsSelfLocked) {
3864                 this.mPidsSelfLocked.put(startResult.pid, app);
3865                 if (isActivityProcess) {
3866                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3867                     msg.obj = app;
3868                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3869                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3870                 }
3871             }
3872             checkTime(startTime, "startProcess: done updating pids map");
3873         } catch (RuntimeException e) {
3874             Slog.e(TAG, "Failure starting process " + app.processName, e);
3875
3876             // Something went very wrong while trying to start this process; one
3877             // common case is when the package is frozen due to an active
3878             // upgrade. To recover, clean up any active bookkeeping related to
3879             // starting this process. (We already invoked this method once when
3880             // the package was initially frozen through KILL_APPLICATION_MSG, so
3881             // it doesn't hurt to use it again.)
3882             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3883                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3884         }
3885     }
3886
3887     void updateUsageStats(ActivityRecord component, boolean resumed) {
3888         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3889                 "updateUsageStats: comp=" + component + "res=" + resumed);
3890         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3891         if (resumed) {
3892             if (mUsageStatsService != null) {
3893                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3894                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3895             }
3896             synchronized (stats) {
3897                 stats.noteActivityResumedLocked(component.app.uid);
3898             }
3899         } else {
3900             if (mUsageStatsService != null) {
3901                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3903             }
3904             synchronized (stats) {
3905                 stats.noteActivityPausedLocked(component.app.uid);
3906             }
3907         }
3908     }
3909
3910     Intent getHomeIntent() {
3911         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3912         intent.setComponent(mTopComponent);
3913         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3914         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3915             intent.addCategory(Intent.CATEGORY_HOME);
3916         }
3917         return intent;
3918     }
3919
3920     boolean startHomeActivityLocked(int userId, String reason) {
3921         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3922                 && mTopAction == null) {
3923             // We are running in factory test mode, but unable to find
3924             // the factory test app, so just sit around displaying the
3925             // error message and don't try to start anything.
3926             return false;
3927         }
3928         Intent intent = getHomeIntent();
3929         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3930         if (aInfo != null) {
3931             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3932             // Don't do this if the home app is currently being
3933             // instrumented.
3934             aInfo = new ActivityInfo(aInfo);
3935             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3936             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3937                     aInfo.applicationInfo.uid, true);
3938             if (app == null || app.instrumentationClass == null) {
3939                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3940                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3941             }
3942         } else {
3943             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3944         }
3945
3946         return true;
3947     }
3948
3949     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3950         ActivityInfo ai = null;
3951         ComponentName comp = intent.getComponent();
3952         try {
3953             if (comp != null) {
3954                 // Factory test.
3955                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3956             } else {
3957                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3958                         intent,
3959                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3960                         flags, userId);
3961
3962                 if (info != null) {
3963                     ai = info.activityInfo;
3964                 }
3965             }
3966         } catch (RemoteException e) {
3967             // ignore
3968         }
3969
3970         return ai;
3971     }
3972
3973     /**
3974      * Starts the "new version setup screen" if appropriate.
3975      */
3976     void startSetupActivityLocked() {
3977         // Only do this once per boot.
3978         if (mCheckedForSetup) {
3979             return;
3980         }
3981
3982         // We will show this screen if the current one is a different
3983         // version than the last one shown, and we are not running in
3984         // low-level factory test mode.
3985         final ContentResolver resolver = mContext.getContentResolver();
3986         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3987                 Settings.Global.getInt(resolver,
3988                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3989             mCheckedForSetup = true;
3990
3991             // See if we should be showing the platform update setup UI.
3992             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3993             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3994                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3995             if (!ris.isEmpty()) {
3996                 final ResolveInfo ri = ris.get(0);
3997                 String vers = ri.activityInfo.metaData != null
3998                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3999                         : null;
4000                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4001                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4002                             Intent.METADATA_SETUP_VERSION);
4003                 }
4004                 String lastVers = Settings.Secure.getString(
4005                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4006                 if (vers != null && !vers.equals(lastVers)) {
4007                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4008                     intent.setComponent(new ComponentName(
4009                             ri.activityInfo.packageName, ri.activityInfo.name));
4010                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4011                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4012                             null, 0, 0, 0, null, false, false, null, null, null);
4013                 }
4014             }
4015         }
4016     }
4017
4018     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4019         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4020     }
4021
4022     void enforceNotIsolatedCaller(String caller) {
4023         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4024             throw new SecurityException("Isolated process not allowed to call " + caller);
4025         }
4026     }
4027
4028     void enforceShellRestriction(String restriction, int userHandle) {
4029         if (Binder.getCallingUid() == Process.SHELL_UID) {
4030             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4031                 throw new SecurityException("Shell does not have permission to access user "
4032                         + userHandle);
4033             }
4034         }
4035     }
4036
4037     @Override
4038     public int getFrontActivityScreenCompatMode() {
4039         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4040         synchronized (this) {
4041             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4042         }
4043     }
4044
4045     @Override
4046     public void setFrontActivityScreenCompatMode(int mode) {
4047         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4048                 "setFrontActivityScreenCompatMode");
4049         synchronized (this) {
4050             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4051         }
4052     }
4053
4054     @Override
4055     public int getPackageScreenCompatMode(String packageName) {
4056         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4057         synchronized (this) {
4058             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4059         }
4060     }
4061
4062     @Override
4063     public void setPackageScreenCompatMode(String packageName, int mode) {
4064         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4065                 "setPackageScreenCompatMode");
4066         synchronized (this) {
4067             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4068         }
4069     }
4070
4071     @Override
4072     public boolean getPackageAskScreenCompat(String packageName) {
4073         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4074         synchronized (this) {
4075             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4076         }
4077     }
4078
4079     @Override
4080     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4081         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4082                 "setPackageAskScreenCompat");
4083         synchronized (this) {
4084             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4085         }
4086     }
4087
4088     private boolean hasUsageStatsPermission(String callingPackage) {
4089         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4090                 Binder.getCallingUid(), callingPackage);
4091         if (mode == AppOpsManager.MODE_DEFAULT) {
4092             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4093                     == PackageManager.PERMISSION_GRANTED;
4094         }
4095         return mode == AppOpsManager.MODE_ALLOWED;
4096     }
4097
4098     @Override
4099     public int getPackageProcessState(String packageName, String callingPackage) {
4100         if (!hasUsageStatsPermission(callingPackage)) {
4101             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4102                     "getPackageProcessState");
4103         }
4104
4105         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4106         synchronized (this) {
4107             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4108                 final ProcessRecord proc = mLruProcesses.get(i);
4109                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4110                         || procState > proc.setProcState) {
4111                     boolean found = false;
4112                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4113                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4114                             procState = proc.setProcState;
4115                             found = true;
4116                         }
4117                     }
4118                     if (proc.pkgDeps != null && !found) {
4119                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4120                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4121                                 procState = proc.setProcState;
4122                                 break;
4123                             }
4124                         }
4125                     }
4126                 }
4127             }
4128         }
4129         return procState;
4130     }
4131
4132     @Override
4133     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4134         synchronized (this) {
4135             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4136             if (app == null) {
4137                 return false;
4138             }
4139             if (app.trimMemoryLevel < level && app.thread != null &&
4140                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4141                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4142                 try {
4143                     app.thread.scheduleTrimMemory(level);
4144                     app.trimMemoryLevel = level;
4145                     return true;
4146                 } catch (RemoteException e) {
4147                     // Fallthrough to failure case.
4148                 }
4149             }
4150         }
4151         return false;
4152     }
4153
4154     private void dispatchProcessesChanged() {
4155         int N;
4156         synchronized (this) {
4157             N = mPendingProcessChanges.size();
4158             if (mActiveProcessChanges.length < N) {
4159                 mActiveProcessChanges = new ProcessChangeItem[N];
4160             }
4161             mPendingProcessChanges.toArray(mActiveProcessChanges);
4162             mPendingProcessChanges.clear();
4163             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4164                     "*** Delivering " + N + " process changes");
4165         }
4166
4167         int i = mProcessObservers.beginBroadcast();
4168         while (i > 0) {
4169             i--;
4170             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4171             if (observer != null) {
4172                 try {
4173                     for (int j=0; j<N; j++) {
4174                         ProcessChangeItem item = mActiveProcessChanges[j];
4175                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4176                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4177                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4178                                     + item.uid + ": " + item.foregroundActivities);
4179                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4180                                     item.foregroundActivities);
4181                         }
4182                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4183                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4184                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4185                                     + ": " + item.processState);
4186                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4187                         }
4188                     }
4189                 } catch (RemoteException e) {
4190                 }
4191             }
4192         }
4193         mProcessObservers.finishBroadcast();
4194
4195         synchronized (this) {
4196             for (int j=0; j<N; j++) {
4197                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4198             }
4199         }
4200     }
4201
4202     private void dispatchProcessDied(int pid, int uid) {
4203         int i = mProcessObservers.beginBroadcast();
4204         while (i > 0) {
4205             i--;
4206             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4207             if (observer != null) {
4208                 try {
4209                     observer.onProcessDied(pid, uid);
4210                 } catch (RemoteException e) {
4211                 }
4212             }
4213         }
4214         mProcessObservers.finishBroadcast();
4215     }
4216
4217     private void dispatchUidsChanged() {
4218         int N;
4219         synchronized (this) {
4220             N = mPendingUidChanges.size();
4221             if (mActiveUidChanges.length < N) {
4222                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4223             }
4224             for (int i=0; i<N; i++) {
4225                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4226                 mActiveUidChanges[i] = change;
4227                 if (change.uidRecord != null) {
4228                     change.uidRecord.pendingChange = null;
4229                     change.uidRecord = null;
4230                 }
4231             }
4232             mPendingUidChanges.clear();
4233             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4234                     "*** Delivering " + N + " uid changes");
4235         }
4236
4237         if (mLocalPowerManager != null) {
4238             for (int j=0; j<N; j++) {
4239                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4240                 if (item.change == UidRecord.CHANGE_GONE
4241                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4242                     mLocalPowerManager.uidGone(item.uid);
4243                 } else {
4244                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4245                 }
4246             }
4247         }
4248
4249         int i = mUidObservers.beginBroadcast();
4250         while (i > 0) {
4251             i--;
4252             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4253             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4254             if (observer != null) {
4255                 try {
4256                     for (int j=0; j<N; j++) {
4257                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4258                         final int change = item.change;
4259                         UidRecord validateUid = null;
4260                         if (VALIDATE_UID_STATES && i == 0) {
4261                             validateUid = mValidateUids.get(item.uid);
4262                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4263                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4264                                 validateUid = new UidRecord(item.uid);
4265                                 mValidateUids.put(item.uid, validateUid);
4266                             }
4267                         }
4268                         if (change == UidRecord.CHANGE_IDLE
4269                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4270                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4271                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4272                                         "UID idle uid=" + item.uid);
4273                                 observer.onUidIdle(item.uid);
4274                             }
4275                             if (VALIDATE_UID_STATES && i == 0) {
4276                                 if (validateUid != null) {
4277                                     validateUid.idle = true;
4278                                 }
4279                             }
4280                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4281                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4282                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4283                                         "UID active uid=" + item.uid);
4284                                 observer.onUidActive(item.uid);
4285                             }
4286                             if (VALIDATE_UID_STATES && i == 0) {
4287                                 validateUid.idle = false;
4288                             }
4289                         }
4290                         if (change == UidRecord.CHANGE_GONE
4291                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4292                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4293                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4294                                         "UID gone uid=" + item.uid);
4295                                 observer.onUidGone(item.uid);
4296                             }
4297                             if (VALIDATE_UID_STATES && i == 0) {
4298                                 if (validateUid != null) {
4299                                     mValidateUids.remove(item.uid);
4300                                 }
4301                             }
4302                         } else {
4303                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4304                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4305                                         "UID CHANGED uid=" + item.uid
4306                                                 + ": " + item.processState);
4307                                 observer.onUidStateChanged(item.uid, item.processState);
4308                             }
4309                             if (VALIDATE_UID_STATES && i == 0) {
4310                                 validateUid.curProcState = validateUid.setProcState
4311                                         = item.processState;
4312                             }
4313                         }
4314                     }
4315                 } catch (RemoteException e) {
4316                 }
4317             }
4318         }
4319         mUidObservers.finishBroadcast();
4320
4321         synchronized (this) {
4322             for (int j=0; j<N; j++) {
4323                 mAvailUidChanges.add(mActiveUidChanges[j]);
4324             }
4325         }
4326     }
4327
4328     @Override
4329     public final int startActivity(IApplicationThread caller, String callingPackage,
4330             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4331             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4332         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4333                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4334                 UserHandle.getCallingUserId());
4335     }
4336
4337     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4338         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4339         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4340                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4341                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4342
4343         // TODO: Switch to user app stacks here.
4344         String mimeType = intent.getType();
4345         final Uri data = intent.getData();
4346         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4347             mimeType = getProviderMimeType(data, userId);
4348         }
4349         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4350
4351         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4352         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4353                 null, 0, 0, null, null, null, null, false, userId, container, null);
4354     }
4355
4356     @Override
4357     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4358             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4360         enforceNotIsolatedCaller("startActivity");
4361         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4362                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4363         // TODO: Switch to user app stacks here.
4364         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4365                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4366                 profilerInfo, null, null, bOptions, false, userId, null, null);
4367     }
4368
4369     @Override
4370     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4371             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4372             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4373             int userId) {
4374
4375         // This is very dangerous -- it allows you to perform a start activity (including
4376         // permission grants) as any app that may launch one of your own activities.  So
4377         // we will only allow this to be done from activities that are part of the core framework,
4378         // and then only when they are running as the system.
4379         final ActivityRecord sourceRecord;
4380         final int targetUid;
4381         final String targetPackage;
4382         synchronized (this) {
4383             if (resultTo == null) {
4384                 throw new SecurityException("Must be called from an activity");
4385             }
4386             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4387             if (sourceRecord == null) {
4388                 throw new SecurityException("Called with bad activity token: " + resultTo);
4389             }
4390             if (!sourceRecord.info.packageName.equals("android")) {
4391                 throw new SecurityException(
4392                         "Must be called from an activity that is declared in the android package");
4393             }
4394             if (sourceRecord.app == null) {
4395                 throw new SecurityException("Called without a process attached to activity");
4396             }
4397             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4398                 // This is still okay, as long as this activity is running under the
4399                 // uid of the original calling activity.
4400                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4401                     throw new SecurityException(
4402                             "Calling activity in uid " + sourceRecord.app.uid
4403                                     + " must be system uid or original calling uid "
4404                                     + sourceRecord.launchedFromUid);
4405                 }
4406             }
4407             if (ignoreTargetSecurity) {
4408                 if (intent.getComponent() == null) {
4409                     throw new SecurityException(
4410                             "Component must be specified with ignoreTargetSecurity");
4411                 }
4412                 if (intent.getSelector() != null) {
4413                     throw new SecurityException(
4414                             "Selector not allowed with ignoreTargetSecurity");
4415                 }
4416             }
4417             targetUid = sourceRecord.launchedFromUid;
4418             targetPackage = sourceRecord.launchedFromPackage;
4419         }
4420
4421         if (userId == UserHandle.USER_NULL) {
4422             userId = UserHandle.getUserId(sourceRecord.app.uid);
4423         }
4424
4425         // TODO: Switch to user app stacks here.
4426         try {
4427             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4428                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4429                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4430             return ret;
4431         } catch (SecurityException e) {
4432             // XXX need to figure out how to propagate to original app.
4433             // A SecurityException here is generally actually a fault of the original
4434             // calling activity (such as a fairly granting permissions), so propagate it
4435             // back to them.
4436             /*
4437             StringBuilder msg = new StringBuilder();
4438             msg.append("While launching");
4439             msg.append(intent.toString());
4440             msg.append(": ");
4441             msg.append(e.getMessage());
4442             */
4443             throw e;
4444         }
4445     }
4446
4447     @Override
4448     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4449             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4450             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4451         enforceNotIsolatedCaller("startActivityAndWait");
4452         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4453                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4454         WaitResult res = new WaitResult();
4455         // TODO: Switch to user app stacks here.
4456         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4457                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4458                 bOptions, false, userId, null, null);
4459         return res;
4460     }
4461
4462     @Override
4463     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4464             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4465             int startFlags, Configuration config, Bundle bOptions, int userId) {
4466         enforceNotIsolatedCaller("startActivityWithConfig");
4467         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4468                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4469         // TODO: Switch to user app stacks here.
4470         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4471                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4472                 null, null, config, bOptions, false, userId, null, null);
4473         return ret;
4474     }
4475
4476     @Override
4477     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4478             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4479             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4480             throws TransactionTooLargeException {
4481         enforceNotIsolatedCaller("startActivityIntentSender");
4482         // Refuse possible leaked file descriptors
4483         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4484             throw new IllegalArgumentException("File descriptors passed in Intent");
4485         }
4486
4487         IIntentSender sender = intent.getTarget();
4488         if (!(sender instanceof PendingIntentRecord)) {
4489             throw new IllegalArgumentException("Bad PendingIntent object");
4490         }
4491
4492         PendingIntentRecord pir = (PendingIntentRecord)sender;
4493
4494         synchronized (this) {
4495             // If this is coming from the currently resumed activity, it is
4496             // effectively saying that app switches are allowed at this point.
4497             final ActivityStack stack = getFocusedStack();
4498             if (stack.mResumedActivity != null &&
4499                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4500                 mAppSwitchesAllowedTime = 0;
4501             }
4502         }
4503         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4504                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4505         return ret;
4506     }
4507
4508     @Override
4509     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4510             Intent intent, String resolvedType, IVoiceInteractionSession session,
4511             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4512             Bundle bOptions, int userId) {
4513         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4514                 != PackageManager.PERMISSION_GRANTED) {
4515             String msg = "Permission Denial: startVoiceActivity() from pid="
4516                     + Binder.getCallingPid()
4517                     + ", uid=" + Binder.getCallingUid()
4518                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4519             Slog.w(TAG, msg);
4520             throw new SecurityException(msg);
4521         }
4522         if (session == null || interactor == null) {
4523             throw new NullPointerException("null session or interactor");
4524         }
4525         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4526                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4527         // TODO: Switch to user app stacks here.
4528         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4529                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4530                 null, bOptions, false, userId, null, null);
4531     }
4532
4533     @Override
4534     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4535             throws RemoteException {
4536         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4537         synchronized (this) {
4538             ActivityRecord activity = getFocusedStack().topActivity();
4539             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4540                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4541             }
4542             if (mRunningVoice != null || activity.task.voiceSession != null
4543                     || activity.voiceSession != null) {
4544                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4545                 return;
4546             }
4547             if (activity.pendingVoiceInteractionStart) {
4548                 Slog.w(TAG, "Pending start of voice interaction already.");
4549                 return;
4550             }
4551             activity.pendingVoiceInteractionStart = true;
4552         }
4553         LocalServices.getService(VoiceInteractionManagerInternal.class)
4554                 .startLocalVoiceInteraction(callingActivity, options);
4555     }
4556
4557     @Override
4558     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4559         LocalServices.getService(VoiceInteractionManagerInternal.class)
4560                 .stopLocalVoiceInteraction(callingActivity);
4561     }
4562
4563     @Override
4564     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4565         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4566                 .supportsLocalVoiceInteraction();
4567     }
4568
4569     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4570             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4571         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4572         if (activityToCallback == null) return;
4573         activityToCallback.setVoiceSessionLocked(voiceSession);
4574
4575         // Inform the activity
4576         try {
4577             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4578                     voiceInteractor);
4579             long token = Binder.clearCallingIdentity();
4580             try {
4581                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4582             } finally {
4583                 Binder.restoreCallingIdentity(token);
4584             }
4585             // TODO: VI Should we cache the activity so that it's easier to find later
4586             // rather than scan through all the stacks and activities?
4587         } catch (RemoteException re) {
4588             activityToCallback.clearVoiceSessionLocked();
4589             // TODO: VI Should this terminate the voice session?
4590         }
4591     }
4592
4593     @Override
4594     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4595         synchronized (this) {
4596             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4597                 if (keepAwake) {
4598                     mVoiceWakeLock.acquire();
4599                 } else {
4600                     mVoiceWakeLock.release();
4601                 }
4602             }
4603         }
4604     }
4605
4606     @Override
4607     public boolean startNextMatchingActivity(IBinder callingActivity,
4608             Intent intent, Bundle bOptions) {
4609         // Refuse possible leaked file descriptors
4610         if (intent != null && intent.hasFileDescriptors() == true) {
4611             throw new IllegalArgumentException("File descriptors passed in Intent");
4612         }
4613         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4614
4615         synchronized (this) {
4616             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4617             if (r == null) {
4618                 ActivityOptions.abort(options);
4619                 return false;
4620             }
4621             if (r.app == null || r.app.thread == null) {
4622                 // The caller is not running...  d'oh!
4623                 ActivityOptions.abort(options);
4624                 return false;
4625             }
4626             intent = new Intent(intent);
4627             // The caller is not allowed to change the data.
4628             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4629             // And we are resetting to find the next component...
4630             intent.setComponent(null);
4631
4632             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4633
4634             ActivityInfo aInfo = null;
4635             try {
4636                 List<ResolveInfo> resolves =
4637                     AppGlobals.getPackageManager().queryIntentActivities(
4638                             intent, r.resolvedType,
4639                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4640                             UserHandle.getCallingUserId()).getList();
4641
4642                 // Look for the original activity in the list...
4643                 final int N = resolves != null ? resolves.size() : 0;
4644                 for (int i=0; i<N; i++) {
4645                     ResolveInfo rInfo = resolves.get(i);
4646                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4647                             && rInfo.activityInfo.name.equals(r.info.name)) {
4648                         // We found the current one...  the next matching is
4649                         // after it.
4650                         i++;
4651                         if (i<N) {
4652                             aInfo = resolves.get(i).activityInfo;
4653                         }
4654                         if (debug) {
4655                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4656                                     + "/" + r.info.name);
4657                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4658                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4659                         }
4660                         break;
4661                     }
4662                 }
4663             } catch (RemoteException e) {
4664             }
4665
4666             if (aInfo == null) {
4667                 // Nobody who is next!
4668                 ActivityOptions.abort(options);
4669                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4670                 return false;
4671             }
4672
4673             intent.setComponent(new ComponentName(
4674                     aInfo.applicationInfo.packageName, aInfo.name));
4675             intent.setFlags(intent.getFlags()&~(
4676                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4677                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4678                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4679                     Intent.FLAG_ACTIVITY_NEW_TASK));
4680
4681             // Okay now we need to start the new activity, replacing the
4682             // currently running activity.  This is a little tricky because
4683             // we want to start the new one as if the current one is finished,
4684             // but not finish the current one first so that there is no flicker.
4685             // And thus...
4686             final boolean wasFinishing = r.finishing;
4687             r.finishing = true;
4688
4689             // Propagate reply information over to the new activity.
4690             final ActivityRecord resultTo = r.resultTo;
4691             final String resultWho = r.resultWho;
4692             final int requestCode = r.requestCode;
4693             r.resultTo = null;
4694             if (resultTo != null) {
4695                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4696             }
4697
4698             final long origId = Binder.clearCallingIdentity();
4699             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4700                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4701                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4702                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4703                     false, false, null, null, null);
4704             Binder.restoreCallingIdentity(origId);
4705
4706             r.finishing = wasFinishing;
4707             if (res != ActivityManager.START_SUCCESS) {
4708                 return false;
4709             }
4710             return true;
4711         }
4712     }
4713
4714     @Override
4715     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4716         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4717             String msg = "Permission Denial: startActivityFromRecents called without " +
4718                     START_TASKS_FROM_RECENTS;
4719             Slog.w(TAG, msg);
4720             throw new SecurityException(msg);
4721         }
4722         final long origId = Binder.clearCallingIdentity();
4723         try {
4724             synchronized (this) {
4725                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4726             }
4727         } finally {
4728             Binder.restoreCallingIdentity(origId);
4729         }
4730     }
4731
4732     final int startActivityInPackage(int uid, String callingPackage,
4733             Intent intent, String resolvedType, IBinder resultTo,
4734             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4735             IActivityContainer container, TaskRecord inTask) {
4736
4737         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4738                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4739
4740         // TODO: Switch to user app stacks here.
4741         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4742                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4743                 null, null, null, bOptions, false, userId, container, inTask);
4744         return ret;
4745     }
4746
4747     @Override
4748     public final int startActivities(IApplicationThread caller, String callingPackage,
4749             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4750             int userId) {
4751         enforceNotIsolatedCaller("startActivities");
4752         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4753                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4754         // TODO: Switch to user app stacks here.
4755         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4756                 resolvedTypes, resultTo, bOptions, userId);
4757         return ret;
4758     }
4759
4760     final int startActivitiesInPackage(int uid, String callingPackage,
4761             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4762             Bundle bOptions, int userId) {
4763
4764         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4765                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4766         // TODO: Switch to user app stacks here.
4767         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4768                 resultTo, bOptions, userId);
4769         return ret;
4770     }
4771
4772     @Override
4773     public void reportActivityFullyDrawn(IBinder token) {
4774         synchronized (this) {
4775             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4776             if (r == null) {
4777                 return;
4778             }
4779             r.reportFullyDrawnLocked();
4780         }
4781     }
4782
4783     @Override
4784     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4785         synchronized (this) {
4786             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4787             if (r == null) {
4788                 return;
4789             }
4790             TaskRecord task = r.task;
4791             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4792                 // Fixed screen orientation isn't supported when activities aren't in full screen
4793                 // mode.
4794                 return;
4795             }
4796             final long origId = Binder.clearCallingIdentity();
4797             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4798             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4799                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4800             if (config != null) {
4801                 r.frozenBeforeDestroy = true;
4802                 if (!updateConfigurationLocked(config, r, false)) {
4803                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4804                 }
4805             }
4806             Binder.restoreCallingIdentity(origId);
4807         }
4808     }
4809
4810     @Override
4811     public int getRequestedOrientation(IBinder token) {
4812         synchronized (this) {
4813             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4814             if (r == null) {
4815                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4816             }
4817             return mWindowManager.getAppOrientation(r.appToken);
4818         }
4819     }
4820
4821     /**
4822      * This is the internal entry point for handling Activity.finish().
4823      *
4824      * @param token The Binder token referencing the Activity we want to finish.
4825      * @param resultCode Result code, if any, from this Activity.
4826      * @param resultData Result data (Intent), if any, from this Activity.
4827      * @param finishTask Whether to finish the task associated with this Activity.
4828      *
4829      * @return Returns true if the activity successfully finished, or false if it is still running.
4830      */
4831     @Override
4832     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4833             int finishTask) {
4834         // Refuse possible leaked file descriptors
4835         if (resultData != null && resultData.hasFileDescriptors() == true) {
4836             throw new IllegalArgumentException("File descriptors passed in Intent");
4837         }
4838
4839         synchronized(this) {
4840             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4841             if (r == null) {
4842                 return true;
4843             }
4844             // Keep track of the root activity of the task before we finish it
4845             TaskRecord tr = r.task;
4846             ActivityRecord rootR = tr.getRootActivity();
4847             if (rootR == null) {
4848                 Slog.w(TAG, "Finishing task with all activities already finished");
4849             }
4850             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4851             // finish.
4852             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4853                     mStackSupervisor.isLastLockedTask(tr)) {
4854                 Slog.i(TAG, "Not finishing task in lock task mode");
4855                 mStackSupervisor.showLockTaskToast();
4856                 return false;
4857             }
4858             if (mController != null) {
4859                 // Find the first activity that is not finishing.
4860                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4861                 if (next != null) {
4862                     // ask watcher if this is allowed
4863                     boolean resumeOK = true;
4864                     try {
4865                         resumeOK = mController.activityResuming(next.packageName);
4866                     } catch (RemoteException e) {
4867                         mController = null;
4868                         Watchdog.getInstance().setActivityController(null);
4869                     }
4870
4871                     if (!resumeOK) {
4872                         Slog.i(TAG, "Not finishing activity because controller resumed");
4873                         return false;
4874                     }
4875                 }
4876             }
4877             final long origId = Binder.clearCallingIdentity();
4878             try {
4879                 boolean res;
4880                 final boolean finishWithRootActivity =
4881                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4882                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4883                         || (finishWithRootActivity && r == rootR)) {
4884                     // If requested, remove the task that is associated to this activity only if it
4885                     // was the root activity in the task. The result code and data is ignored
4886                     // because we don't support returning them across task boundaries. Also, to
4887                     // keep backwards compatibility we remove the task from recents when finishing
4888                     // task with root activity.
4889                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4890                     if (!res) {
4891                         Slog.i(TAG, "Removing task failed to finish activity");
4892                     }
4893                 } else {
4894                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4895                             resultData, "app-request", true);
4896                     if (!res) {
4897                         Slog.i(TAG, "Failed to finish by app-request");
4898                     }
4899                 }
4900                 return res;
4901             } finally {
4902                 Binder.restoreCallingIdentity(origId);
4903             }
4904         }
4905     }
4906
4907     @Override
4908     public final void finishHeavyWeightApp() {
4909         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4910                 != PackageManager.PERMISSION_GRANTED) {
4911             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4912                     + Binder.getCallingPid()
4913                     + ", uid=" + Binder.getCallingUid()
4914                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4915             Slog.w(TAG, msg);
4916             throw new SecurityException(msg);
4917         }
4918
4919         synchronized(this) {
4920             if (mHeavyWeightProcess == null) {
4921                 return;
4922             }
4923
4924             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4925             for (int i = 0; i < activities.size(); i++) {
4926                 ActivityRecord r = activities.get(i);
4927                 if (!r.finishing && r.isInStackLocked()) {
4928                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4929                             null, "finish-heavy", true);
4930                 }
4931             }
4932
4933             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4934                     mHeavyWeightProcess.userId, 0));
4935             mHeavyWeightProcess = null;
4936         }
4937     }
4938
4939     @Override
4940     public void crashApplication(int uid, int initialPid, String packageName,
4941             String message) {
4942         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4943                 != PackageManager.PERMISSION_GRANTED) {
4944             String msg = "Permission Denial: crashApplication() from pid="
4945                     + Binder.getCallingPid()
4946                     + ", uid=" + Binder.getCallingUid()
4947                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4948             Slog.w(TAG, msg);
4949             throw new SecurityException(msg);
4950         }
4951
4952         synchronized(this) {
4953             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4954         }
4955     }
4956
4957     @Override
4958     public final void finishSubActivity(IBinder token, String resultWho,
4959             int requestCode) {
4960         synchronized(this) {
4961             final long origId = Binder.clearCallingIdentity();
4962             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4963             if (r != null) {
4964                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4965             }
4966             Binder.restoreCallingIdentity(origId);
4967         }
4968     }
4969
4970     @Override
4971     public boolean finishActivityAffinity(IBinder token) {
4972         synchronized(this) {
4973             final long origId = Binder.clearCallingIdentity();
4974             try {
4975                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4976                 if (r == null) {
4977                     return false;
4978                 }
4979
4980                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4981                 // can finish.
4982                 final TaskRecord task = r.task;
4983                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4984                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4985                     mStackSupervisor.showLockTaskToast();
4986                     return false;
4987                 }
4988                 return task.stack.finishActivityAffinityLocked(r);
4989             } finally {
4990                 Binder.restoreCallingIdentity(origId);
4991             }
4992         }
4993     }
4994
4995     @Override
4996     public void finishVoiceTask(IVoiceInteractionSession session) {
4997         synchronized (this) {
4998             final long origId = Binder.clearCallingIdentity();
4999             try {
5000                 // TODO: VI Consider treating local voice interactions and voice tasks
5001                 // differently here
5002                 mStackSupervisor.finishVoiceTask(session);
5003             } finally {
5004                 Binder.restoreCallingIdentity(origId);
5005             }
5006         }
5007
5008     }
5009
5010     @Override
5011     public boolean releaseActivityInstance(IBinder token) {
5012         synchronized(this) {
5013             final long origId = Binder.clearCallingIdentity();
5014             try {
5015                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5016                 if (r == null) {
5017                     return false;
5018                 }
5019                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5020             } finally {
5021                 Binder.restoreCallingIdentity(origId);
5022             }
5023         }
5024     }
5025
5026     @Override
5027     public void releaseSomeActivities(IApplicationThread appInt) {
5028         synchronized(this) {
5029             final long origId = Binder.clearCallingIdentity();
5030             try {
5031                 ProcessRecord app = getRecordForAppLocked(appInt);
5032                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5033             } finally {
5034                 Binder.restoreCallingIdentity(origId);
5035             }
5036         }
5037     }
5038
5039     @Override
5040     public boolean willActivityBeVisible(IBinder token) {
5041         synchronized(this) {
5042             ActivityStack stack = ActivityRecord.getStackLocked(token);
5043             if (stack != null) {
5044                 return stack.willActivityBeVisibleLocked(token);
5045             }
5046             return false;
5047         }
5048     }
5049
5050     @Override
5051     public void overridePendingTransition(IBinder token, String packageName,
5052             int enterAnim, int exitAnim) {
5053         synchronized(this) {
5054             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5055             if (self == null) {
5056                 return;
5057             }
5058
5059             final long origId = Binder.clearCallingIdentity();
5060
5061             if (self.state == ActivityState.RESUMED
5062                     || self.state == ActivityState.PAUSING) {
5063                 mWindowManager.overridePendingAppTransition(packageName,
5064                         enterAnim, exitAnim, null);
5065             }
5066
5067             Binder.restoreCallingIdentity(origId);
5068         }
5069     }
5070
5071     /**
5072      * Main function for removing an existing process from the activity manager
5073      * as a result of that process going away.  Clears out all connections
5074      * to the process.
5075      */
5076     private final void handleAppDiedLocked(ProcessRecord app,
5077             boolean restarting, boolean allowRestart) {
5078         int pid = app.pid;
5079         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5080                 false /*replacingPid*/);
5081         if (!kept && !restarting) {
5082             removeLruProcessLocked(app);
5083             if (pid > 0) {
5084                 ProcessList.remove(pid);
5085             }
5086         }
5087
5088         if (mProfileProc == app) {
5089             clearProfilerLocked();
5090         }
5091
5092         // Remove this application's activities from active lists.
5093         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5094
5095         app.activities.clear();
5096
5097         if (app.instrumentationClass != null) {
5098             Slog.w(TAG, "Crash of app " + app.processName
5099                   + " running instrumentation " + app.instrumentationClass);
5100             Bundle info = new Bundle();
5101             info.putString("shortMsg", "Process crashed.");
5102             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5103         }
5104
5105         if (!restarting && hasVisibleActivities
5106                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5107             // If there was nothing to resume, and we are not already restarting this process, but
5108             // there is a visible activity that is hosted by the process...  then make sure all
5109             // visible activities are running, taking care of restarting this process.
5110             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5111         }
5112     }
5113
5114     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5115         IBinder threadBinder = thread.asBinder();
5116         // Find the application record.
5117         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5118             ProcessRecord rec = mLruProcesses.get(i);
5119             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5120                 return i;
5121             }
5122         }
5123         return -1;
5124     }
5125
5126     final ProcessRecord getRecordForAppLocked(
5127             IApplicationThread thread) {
5128         if (thread == null) {
5129             return null;
5130         }
5131
5132         int appIndex = getLRURecordIndexForAppLocked(thread);
5133         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5134     }
5135
5136     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5137         // If there are no longer any background processes running,
5138         // and the app that died was not running instrumentation,
5139         // then tell everyone we are now low on memory.
5140         boolean haveBg = false;
5141         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5142             ProcessRecord rec = mLruProcesses.get(i);
5143             if (rec.thread != null
5144                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5145                 haveBg = true;
5146                 break;
5147             }
5148         }
5149
5150         if (!haveBg) {
5151             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5152             if (doReport) {
5153                 long now = SystemClock.uptimeMillis();
5154                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5155                     doReport = false;
5156                 } else {
5157                     mLastMemUsageReportTime = now;
5158                 }
5159             }
5160             final ArrayList<ProcessMemInfo> memInfos
5161                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5162             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5163             long now = SystemClock.uptimeMillis();
5164             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5165                 ProcessRecord rec = mLruProcesses.get(i);
5166                 if (rec == dyingProc || rec.thread == null) {
5167                     continue;
5168                 }
5169                 if (doReport) {
5170                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5171                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5172                 }
5173                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5174                     // The low memory report is overriding any current
5175                     // state for a GC request.  Make sure to do
5176                     // heavy/important/visible/foreground processes first.
5177                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5178                         rec.lastRequestedGc = 0;
5179                     } else {
5180                         rec.lastRequestedGc = rec.lastLowMemory;
5181                     }
5182                     rec.reportLowMemory = true;
5183                     rec.lastLowMemory = now;
5184                     mProcessesToGc.remove(rec);
5185                     addProcessToGcListLocked(rec);
5186                 }
5187             }
5188             if (doReport) {
5189                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5190                 mHandler.sendMessage(msg);
5191             }
5192             scheduleAppGcsLocked();
5193         }
5194     }
5195
5196     final void appDiedLocked(ProcessRecord app) {
5197        appDiedLocked(app, app.pid, app.thread, false);
5198     }
5199
5200     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5201             boolean fromBinderDied) {
5202         // First check if this ProcessRecord is actually active for the pid.
5203         synchronized (mPidsSelfLocked) {
5204             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5205             if (curProc != app) {
5206                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5207                 return;
5208             }
5209         }
5210
5211         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5212         synchronized (stats) {
5213             stats.noteProcessDiedLocked(app.info.uid, pid);
5214         }
5215
5216         if (!app.killed) {
5217             if (!fromBinderDied) {
5218                 Process.killProcessQuiet(pid);
5219             }
5220             killProcessGroup(app.uid, pid);
5221             app.killed = true;
5222         }
5223
5224         // Clean up already done if the process has been re-started.
5225         if (app.pid == pid && app.thread != null &&
5226                 app.thread.asBinder() == thread.asBinder()) {
5227             boolean doLowMem = app.instrumentationClass == null;
5228             boolean doOomAdj = doLowMem;
5229             if (!app.killedByAm) {
5230                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5231                         + ") has died");
5232                 mAllowLowerMemLevel = true;
5233             } else {
5234                 // Note that we always want to do oom adj to update our state with the
5235                 // new number of procs.
5236                 mAllowLowerMemLevel = false;
5237                 doLowMem = false;
5238             }
5239             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5240             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5241                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5242             handleAppDiedLocked(app, false, true);
5243
5244             if (doOomAdj) {
5245                 updateOomAdjLocked();
5246             }
5247             if (doLowMem) {
5248                 doLowMemReportIfNeededLocked(app);
5249             }
5250         } else if (app.pid != pid) {
5251             // A new process has already been started.
5252             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5253                     + ") has died and restarted (pid " + app.pid + ").");
5254             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5255         } else if (DEBUG_PROCESSES) {
5256             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5257                     + thread.asBinder());
5258         }
5259     }
5260
5261     /**
5262      * If a stack trace dump file is configured, dump process stack traces.
5263      * @param clearTraces causes the dump file to be erased prior to the new
5264      *    traces being written, if true; when false, the new traces will be
5265      *    appended to any existing file content.
5266      * @param firstPids of dalvik VM processes to dump stack traces for first
5267      * @param lastPids of dalvik VM processes to dump stack traces for last
5268      * @param nativeProcs optional list of native process names to dump stack crawls
5269      * @return file containing stack traces, or null if no dump file is configured
5270      */
5271     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5272             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5273         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5274         if (tracesPath == null || tracesPath.length() == 0) {
5275             return null;
5276         }
5277
5278         File tracesFile = new File(tracesPath);
5279         try {
5280             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5281             tracesFile.createNewFile();
5282             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5283         } catch (IOException e) {
5284             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5285             return null;
5286         }
5287
5288         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5289         return tracesFile;
5290     }
5291
5292     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5293             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5294         // Use a FileObserver to detect when traces finish writing.
5295         // The order of traces is considered important to maintain for legibility.
5296         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5297             @Override
5298             public synchronized void onEvent(int event, String path) { notify(); }
5299         };
5300
5301         try {
5302             observer.startWatching();
5303
5304             // First collect all of the stacks of the most important pids.
5305             if (firstPids != null) {
5306                 try {
5307                     int num = firstPids.size();
5308                     for (int i = 0; i < num; i++) {
5309                         synchronized (observer) {
5310                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5311                                     + firstPids.get(i));
5312                             final long sime = SystemClock.elapsedRealtime();
5313                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5314                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5315                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5316                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5317                         }
5318                     }
5319                 } catch (InterruptedException e) {
5320                     Slog.wtf(TAG, e);
5321                 }
5322             }
5323
5324             // Next collect the stacks of the native pids
5325             if (nativeProcs != null) {
5326                 int[] pids = Process.getPidsForCommands(nativeProcs);
5327                 if (pids != null) {
5328                     for (int pid : pids) {
5329                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5330                         final long sime = SystemClock.elapsedRealtime();
5331                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5332                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5333                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5334                     }
5335                 }
5336             }
5337
5338             // Lastly, measure CPU usage.
5339             if (processCpuTracker != null) {
5340                 processCpuTracker.init();
5341                 System.gc();
5342                 processCpuTracker.update();
5343                 try {
5344                     synchronized (processCpuTracker) {
5345                         processCpuTracker.wait(500); // measure over 1/2 second.
5346                     }
5347                 } catch (InterruptedException e) {
5348                 }
5349                 processCpuTracker.update();
5350
5351                 // We'll take the stack crawls of just the top apps using CPU.
5352                 final int N = processCpuTracker.countWorkingStats();
5353                 int numProcs = 0;
5354                 for (int i=0; i<N && numProcs<5; i++) {
5355                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5356                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5357                         numProcs++;
5358                         try {
5359                             synchronized (observer) {
5360                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5361                                         + stats.pid);
5362                                 final long stime = SystemClock.elapsedRealtime();
5363                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5364                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5365                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5366                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5367                             }
5368                         } catch (InterruptedException e) {
5369                             Slog.wtf(TAG, e);
5370                         }
5371                     } else if (DEBUG_ANR) {
5372                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5373                                 + stats.pid);
5374                     }
5375                 }
5376             }
5377         } finally {
5378             observer.stopWatching();
5379         }
5380     }
5381
5382     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5383         if (true || IS_USER_BUILD) {
5384             return;
5385         }
5386         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5387         if (tracesPath == null || tracesPath.length() == 0) {
5388             return;
5389         }
5390
5391         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5392         StrictMode.allowThreadDiskWrites();
5393         try {
5394             final File tracesFile = new File(tracesPath);
5395             final File tracesDir = tracesFile.getParentFile();
5396             final File tracesTmp = new File(tracesDir, "__tmp__");
5397             try {
5398                 if (tracesFile.exists()) {
5399                     tracesTmp.delete();
5400                     tracesFile.renameTo(tracesTmp);
5401                 }
5402                 StringBuilder sb = new StringBuilder();
5403                 Time tobj = new Time();
5404                 tobj.set(System.currentTimeMillis());
5405                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5406                 sb.append(": ");
5407                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5408                 sb.append(" since ");
5409                 sb.append(msg);
5410                 FileOutputStream fos = new FileOutputStream(tracesFile);
5411                 fos.write(sb.toString().getBytes());
5412                 if (app == null) {
5413                     fos.write("\n*** No application process!".getBytes());
5414                 }
5415                 fos.close();
5416                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5417             } catch (IOException e) {
5418                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5419                 return;
5420             }
5421
5422             if (app != null) {
5423                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5424                 firstPids.add(app.pid);
5425                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5426             }
5427
5428             File lastTracesFile = null;
5429             File curTracesFile = null;
5430             for (int i=9; i>=0; i--) {
5431                 String name = String.format(Locale.US, "slow%02d.txt", i);
5432                 curTracesFile = new File(tracesDir, name);
5433                 if (curTracesFile.exists()) {
5434                     if (lastTracesFile != null) {
5435                         curTracesFile.renameTo(lastTracesFile);
5436                     } else {
5437                         curTracesFile.delete();
5438                     }
5439                 }
5440                 lastTracesFile = curTracesFile;
5441             }
5442             tracesFile.renameTo(curTracesFile);
5443             if (tracesTmp.exists()) {
5444                 tracesTmp.renameTo(tracesFile);
5445             }
5446         } finally {
5447             StrictMode.setThreadPolicy(oldPolicy);
5448         }
5449     }
5450
5451     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5452         if (!mLaunchWarningShown) {
5453             mLaunchWarningShown = true;
5454             mUiHandler.post(new Runnable() {
5455                 @Override
5456                 public void run() {
5457                     synchronized (ActivityManagerService.this) {
5458                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5459                         d.show();
5460                         mUiHandler.postDelayed(new Runnable() {
5461                             @Override
5462                             public void run() {
5463                                 synchronized (ActivityManagerService.this) {
5464                                     d.dismiss();
5465                                     mLaunchWarningShown = false;
5466                                 }
5467                             }
5468                         }, 4000);
5469                     }
5470                 }
5471             });
5472         }
5473     }
5474
5475     @Override
5476     public boolean clearApplicationUserData(final String packageName,
5477             final IPackageDataObserver observer, int userId) {
5478         enforceNotIsolatedCaller("clearApplicationUserData");
5479         int uid = Binder.getCallingUid();
5480         int pid = Binder.getCallingPid();
5481         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5482                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5483
5484
5485         long callingId = Binder.clearCallingIdentity();
5486         try {
5487             IPackageManager pm = AppGlobals.getPackageManager();
5488             int pkgUid = -1;
5489             synchronized(this) {
5490                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5491                         userId, packageName)) {
5492                     throw new SecurityException(
5493                             "Cannot clear data for a protected package: " + packageName);
5494                 }
5495
5496                 try {
5497                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5498                 } catch (RemoteException e) {
5499                 }
5500                 if (pkgUid == -1) {
5501                     Slog.w(TAG, "Invalid packageName: " + packageName);
5502                     if (observer != null) {
5503                         try {
5504                             observer.onRemoveCompleted(packageName, false);
5505                         } catch (RemoteException e) {
5506                             Slog.i(TAG, "Observer no longer exists.");
5507                         }
5508                     }
5509                     return false;
5510                 }
5511                 if (uid == pkgUid || checkComponentPermission(
5512                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5513                         pid, uid, -1, true)
5514                         == PackageManager.PERMISSION_GRANTED) {
5515                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5516                 } else {
5517                     throw new SecurityException("PID " + pid + " does not have permission "
5518                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5519                                     + " of package " + packageName);
5520                 }
5521
5522                 // Remove all tasks match the cleared application package and user
5523                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5524                     final TaskRecord tr = mRecentTasks.get(i);
5525                     final String taskPackageName =
5526                             tr.getBaseIntent().getComponent().getPackageName();
5527                     if (tr.userId != userId) continue;
5528                     if (!taskPackageName.equals(packageName)) continue;
5529                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5530                 }
5531             }
5532
5533             final int pkgUidF = pkgUid;
5534             final int userIdF = userId;
5535             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5536                 @Override
5537                 public void onRemoveCompleted(String packageName, boolean succeeded)
5538                         throws RemoteException {
5539                     synchronized (ActivityManagerService.this) {
5540                         finishForceStopPackageLocked(packageName, pkgUidF);
5541                     }
5542
5543                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5544                             Uri.fromParts("package", packageName, null));
5545                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5546                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5547                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5548                             null, null, 0, null, null, null, null, false, false, userIdF);
5549
5550                     if (observer != null) {
5551                         observer.onRemoveCompleted(packageName, succeeded);
5552                     }
5553                 }
5554             };
5555
5556             try {
5557                 // Clear application user data
5558                 pm.clearApplicationUserData(packageName, localObserver, userId);
5559
5560                 synchronized(this) {
5561                     // Remove all permissions granted from/to this package
5562                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5563                 }
5564
5565                 // Remove all zen rules created by this package; revoke it's zen access.
5566                 INotificationManager inm = NotificationManager.getService();
5567                 inm.removeAutomaticZenRules(packageName);
5568                 inm.setNotificationPolicyAccessGranted(packageName, false);
5569
5570             } catch (RemoteException e) {
5571             }
5572         } finally {
5573             Binder.restoreCallingIdentity(callingId);
5574         }
5575         return true;
5576     }
5577
5578     @Override
5579     public void killBackgroundProcesses(final String packageName, int userId) {
5580         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5581                 != PackageManager.PERMISSION_GRANTED &&
5582                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5583                         != PackageManager.PERMISSION_GRANTED) {
5584             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5585                     + Binder.getCallingPid()
5586                     + ", uid=" + Binder.getCallingUid()
5587                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5588             Slog.w(TAG, msg);
5589             throw new SecurityException(msg);
5590         }
5591
5592         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5593                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5594         long callingId = Binder.clearCallingIdentity();
5595         try {
5596             IPackageManager pm = AppGlobals.getPackageManager();
5597             synchronized(this) {
5598                 int appId = -1;
5599                 try {
5600                     appId = UserHandle.getAppId(
5601                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5602                 } catch (RemoteException e) {
5603                 }
5604                 if (appId == -1) {
5605                     Slog.w(TAG, "Invalid packageName: " + packageName);
5606                     return;
5607                 }
5608                 killPackageProcessesLocked(packageName, appId, userId,
5609                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5610             }
5611         } finally {
5612             Binder.restoreCallingIdentity(callingId);
5613         }
5614     }
5615
5616     @Override
5617     public void killAllBackgroundProcesses() {
5618         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5619                 != PackageManager.PERMISSION_GRANTED) {
5620             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5621                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5622                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5623             Slog.w(TAG, msg);
5624             throw new SecurityException(msg);
5625         }
5626
5627         final long callingId = Binder.clearCallingIdentity();
5628         try {
5629             synchronized (this) {
5630                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5631                 final int NP = mProcessNames.getMap().size();
5632                 for (int ip = 0; ip < NP; ip++) {
5633                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5634                     final int NA = apps.size();
5635                     for (int ia = 0; ia < NA; ia++) {
5636                         final ProcessRecord app = apps.valueAt(ia);
5637                         if (app.persistent) {
5638                             // We don't kill persistent processes.
5639                             continue;
5640                         }
5641                         if (app.removed) {
5642                             procs.add(app);
5643                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5644                             app.removed = true;
5645                             procs.add(app);
5646                         }
5647                     }
5648                 }
5649
5650                 final int N = procs.size();
5651                 for (int i = 0; i < N; i++) {
5652                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5653                 }
5654
5655                 mAllowLowerMemLevel = true;
5656
5657                 updateOomAdjLocked();
5658                 doLowMemReportIfNeededLocked(null);
5659             }
5660         } finally {
5661             Binder.restoreCallingIdentity(callingId);
5662         }
5663     }
5664
5665     /**
5666      * Kills all background processes, except those matching any of the
5667      * specified properties.
5668      *
5669      * @param minTargetSdk the target SDK version at or above which to preserve
5670      *                     processes, or {@code -1} to ignore the target SDK
5671      * @param maxProcState the process state at or below which to preserve
5672      *                     processes, or {@code -1} to ignore the process state
5673      */
5674     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5675         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5676                 != PackageManager.PERMISSION_GRANTED) {
5677             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5678                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5679                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5680             Slog.w(TAG, msg);
5681             throw new SecurityException(msg);
5682         }
5683
5684         final long callingId = Binder.clearCallingIdentity();
5685         try {
5686             synchronized (this) {
5687                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5688                 final int NP = mProcessNames.getMap().size();
5689                 for (int ip = 0; ip < NP; ip++) {
5690                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5691                     final int NA = apps.size();
5692                     for (int ia = 0; ia < NA; ia++) {
5693                         final ProcessRecord app = apps.valueAt(ia);
5694                         if (app.removed) {
5695                             procs.add(app);
5696                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5697                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5698                             app.removed = true;
5699                             procs.add(app);
5700                         }
5701                     }
5702                 }
5703
5704                 final int N = procs.size();
5705                 for (int i = 0; i < N; i++) {
5706                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5707                 }
5708             }
5709         } finally {
5710             Binder.restoreCallingIdentity(callingId);
5711         }
5712     }
5713
5714     @Override
5715     public void forceStopPackage(final String packageName, int userId) {
5716         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5717                 != PackageManager.PERMISSION_GRANTED) {
5718             String msg = "Permission Denial: forceStopPackage() from pid="
5719                     + Binder.getCallingPid()
5720                     + ", uid=" + Binder.getCallingUid()
5721                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5722             Slog.w(TAG, msg);
5723             throw new SecurityException(msg);
5724         }
5725         final int callingPid = Binder.getCallingPid();
5726         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5727                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5728         long callingId = Binder.clearCallingIdentity();
5729         try {
5730             IPackageManager pm = AppGlobals.getPackageManager();
5731             synchronized(this) {
5732                 int[] users = userId == UserHandle.USER_ALL
5733                         ? mUserController.getUsers() : new int[] { userId };
5734                 for (int user : users) {
5735                     int pkgUid = -1;
5736                     try {
5737                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5738                                 user);
5739                     } catch (RemoteException e) {
5740                     }
5741                     if (pkgUid == -1) {
5742                         Slog.w(TAG, "Invalid packageName: " + packageName);
5743                         continue;
5744                     }
5745                     try {
5746                         pm.setPackageStoppedState(packageName, true, user);
5747                     } catch (RemoteException e) {
5748                     } catch (IllegalArgumentException e) {
5749                         Slog.w(TAG, "Failed trying to unstop package "
5750                                 + packageName + ": " + e);
5751                     }
5752                     if (mUserController.isUserRunningLocked(user, 0)) {
5753                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5754                         finishForceStopPackageLocked(packageName, pkgUid);
5755                     }
5756                 }
5757             }
5758         } finally {
5759             Binder.restoreCallingIdentity(callingId);
5760         }
5761     }
5762
5763     @Override
5764     public void addPackageDependency(String packageName) {
5765         synchronized (this) {
5766             int callingPid = Binder.getCallingPid();
5767             if (callingPid == Process.myPid()) {
5768                 //  Yeah, um, no.
5769                 return;
5770             }
5771             ProcessRecord proc;
5772             synchronized (mPidsSelfLocked) {
5773                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5774             }
5775             if (proc != null) {
5776                 if (proc.pkgDeps == null) {
5777                     proc.pkgDeps = new ArraySet<String>(1);
5778                 }
5779                 proc.pkgDeps.add(packageName);
5780             }
5781         }
5782     }
5783
5784     /*
5785      * The pkg name and app id have to be specified.
5786      */
5787     @Override
5788     public void killApplication(String pkg, int appId, int userId, String reason) {
5789         if (pkg == null) {
5790             return;
5791         }
5792         // Make sure the uid is valid.
5793         if (appId < 0) {
5794             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5795             return;
5796         }
5797         int callerUid = Binder.getCallingUid();
5798         // Only the system server can kill an application
5799         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5800             // Post an aysnc message to kill the application
5801             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5802             msg.arg1 = appId;
5803             msg.arg2 = userId;
5804             Bundle bundle = new Bundle();
5805             bundle.putString("pkg", pkg);
5806             bundle.putString("reason", reason);
5807             msg.obj = bundle;
5808             mHandler.sendMessage(msg);
5809         } else {
5810             throw new SecurityException(callerUid + " cannot kill pkg: " +
5811                     pkg);
5812         }
5813     }
5814
5815     @Override
5816     public void closeSystemDialogs(String reason) {
5817         enforceNotIsolatedCaller("closeSystemDialogs");
5818
5819         final int pid = Binder.getCallingPid();
5820         final int uid = Binder.getCallingUid();
5821         final long origId = Binder.clearCallingIdentity();
5822         try {
5823             synchronized (this) {
5824                 // Only allow this from foreground processes, so that background
5825                 // applications can't abuse it to prevent system UI from being shown.
5826                 if (uid >= Process.FIRST_APPLICATION_UID) {
5827                     ProcessRecord proc;
5828                     synchronized (mPidsSelfLocked) {
5829                         proc = mPidsSelfLocked.get(pid);
5830                     }
5831                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5832                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5833                                 + " from background process " + proc);
5834                         return;
5835                     }
5836                 }
5837                 closeSystemDialogsLocked(reason);
5838             }
5839         } finally {
5840             Binder.restoreCallingIdentity(origId);
5841         }
5842     }
5843
5844     void closeSystemDialogsLocked(String reason) {
5845         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5846         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5847                 | Intent.FLAG_RECEIVER_FOREGROUND);
5848         if (reason != null) {
5849             intent.putExtra("reason", reason);
5850         }
5851         mWindowManager.closeSystemDialogs(reason);
5852
5853         mStackSupervisor.closeSystemDialogsLocked();
5854
5855         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5856                 AppOpsManager.OP_NONE, null, false, false,
5857                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5858     }
5859
5860     @Override
5861     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5862         enforceNotIsolatedCaller("getProcessMemoryInfo");
5863         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5864         for (int i=pids.length-1; i>=0; i--) {
5865             ProcessRecord proc;
5866             int oomAdj;
5867             synchronized (this) {
5868                 synchronized (mPidsSelfLocked) {
5869                     proc = mPidsSelfLocked.get(pids[i]);
5870                     oomAdj = proc != null ? proc.setAdj : 0;
5871                 }
5872             }
5873             infos[i] = new Debug.MemoryInfo();
5874             Debug.getMemoryInfo(pids[i], infos[i]);
5875             if (proc != null) {
5876                 synchronized (this) {
5877                     if (proc.thread != null && proc.setAdj == oomAdj) {
5878                         // Record this for posterity if the process has been stable.
5879                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5880                                 infos[i].getTotalUss(), false, proc.pkgList);
5881                     }
5882                 }
5883             }
5884         }
5885         return infos;
5886     }
5887
5888     @Override
5889     public long[] getProcessPss(int[] pids) {
5890         enforceNotIsolatedCaller("getProcessPss");
5891         long[] pss = new long[pids.length];
5892         for (int i=pids.length-1; i>=0; i--) {
5893             ProcessRecord proc;
5894             int oomAdj;
5895             synchronized (this) {
5896                 synchronized (mPidsSelfLocked) {
5897                     proc = mPidsSelfLocked.get(pids[i]);
5898                     oomAdj = proc != null ? proc.setAdj : 0;
5899                 }
5900             }
5901             long[] tmpUss = new long[1];
5902             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5903             if (proc != null) {
5904                 synchronized (this) {
5905                     if (proc.thread != null && proc.setAdj == oomAdj) {
5906                         // Record this for posterity if the process has been stable.
5907                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5908                     }
5909                 }
5910             }
5911         }
5912         return pss;
5913     }
5914
5915     @Override
5916     public void killApplicationProcess(String processName, int uid) {
5917         if (processName == null) {
5918             return;
5919         }
5920
5921         int callerUid = Binder.getCallingUid();
5922         // Only the system server can kill an application
5923         if (callerUid == Process.SYSTEM_UID) {
5924             synchronized (this) {
5925                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5926                 if (app != null && app.thread != null) {
5927                     try {
5928                         app.thread.scheduleSuicide();
5929                     } catch (RemoteException e) {
5930                         // If the other end already died, then our work here is done.
5931                     }
5932                 } else {
5933                     Slog.w(TAG, "Process/uid not found attempting kill of "
5934                             + processName + " / " + uid);
5935                 }
5936             }
5937         } else {
5938             throw new SecurityException(callerUid + " cannot kill app process: " +
5939                     processName);
5940         }
5941     }
5942
5943     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5944         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5945                 false, true, false, false, UserHandle.getUserId(uid), reason);
5946     }
5947
5948     private void finishForceStopPackageLocked(final String packageName, int uid) {
5949         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5950                 Uri.fromParts("package", packageName, null));
5951         if (!mProcessesReady) {
5952             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5953                     | Intent.FLAG_RECEIVER_FOREGROUND);
5954         }
5955         intent.putExtra(Intent.EXTRA_UID, uid);
5956         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5957         broadcastIntentLocked(null, null, intent,
5958                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5959                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5960     }
5961
5962
5963     private final boolean killPackageProcessesLocked(String packageName, int appId,
5964             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5965             boolean doit, boolean evenPersistent, String reason) {
5966         ArrayList<ProcessRecord> procs = new ArrayList<>();
5967
5968         // Remove all processes this package may have touched: all with the
5969         // same UID (except for the system or root user), and all whose name
5970         // matches the package name.
5971         final int NP = mProcessNames.getMap().size();
5972         for (int ip=0; ip<NP; ip++) {
5973             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5974             final int NA = apps.size();
5975             for (int ia=0; ia<NA; ia++) {
5976                 ProcessRecord app = apps.valueAt(ia);
5977                 if (app.persistent && !evenPersistent) {
5978                     // we don't kill persistent processes
5979                     continue;
5980                 }
5981                 if (app.removed) {
5982                     if (doit) {
5983                         procs.add(app);
5984                     }
5985                     continue;
5986                 }
5987
5988                 // Skip process if it doesn't meet our oom adj requirement.
5989                 if (app.setAdj < minOomAdj) {
5990                     continue;
5991                 }
5992
5993                 // If no package is specified, we call all processes under the
5994                 // give user id.
5995                 if (packageName == null) {
5996                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5997                         continue;
5998                     }
5999                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6000                         continue;
6001                     }
6002                 // Package has been specified, we want to hit all processes
6003                 // that match it.  We need to qualify this by the processes
6004                 // that are running under the specified app and user ID.
6005                 } else {
6006                     final boolean isDep = app.pkgDeps != null
6007                             && app.pkgDeps.contains(packageName);
6008                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6009                         continue;
6010                     }
6011                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6012                         continue;
6013                     }
6014                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6015                         continue;
6016                     }
6017                 }
6018
6019                 // Process has passed all conditions, kill it!
6020                 if (!doit) {
6021                     return true;
6022                 }
6023                 app.removed = true;
6024                 procs.add(app);
6025             }
6026         }
6027
6028         int N = procs.size();
6029         for (int i=0; i<N; i++) {
6030             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6031         }
6032         updateOomAdjLocked();
6033         return N > 0;
6034     }
6035
6036     private void cleanupDisabledPackageComponentsLocked(
6037             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6038
6039         Set<String> disabledClasses = null;
6040         boolean packageDisabled = false;
6041         IPackageManager pm = AppGlobals.getPackageManager();
6042
6043         if (changedClasses == null) {
6044             // Nothing changed...
6045             return;
6046         }
6047
6048         // Determine enable/disable state of the package and its components.
6049         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6050         for (int i = changedClasses.length - 1; i >= 0; i--) {
6051             final String changedClass = changedClasses[i];
6052
6053             if (changedClass.equals(packageName)) {
6054                 try {
6055                     // Entire package setting changed
6056                     enabled = pm.getApplicationEnabledSetting(packageName,
6057                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6058                 } catch (Exception e) {
6059                     // No such package/component; probably racing with uninstall.  In any
6060                     // event it means we have nothing further to do here.
6061                     return;
6062                 }
6063                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6064                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6065                 if (packageDisabled) {
6066                     // Entire package is disabled.
6067                     // No need to continue to check component states.
6068                     disabledClasses = null;
6069                     break;
6070                 }
6071             } else {
6072                 try {
6073                     enabled = pm.getComponentEnabledSetting(
6074                             new ComponentName(packageName, changedClass),
6075                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6076                 } catch (Exception e) {
6077                     // As above, probably racing with uninstall.
6078                     return;
6079                 }
6080                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6081                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6082                     if (disabledClasses == null) {
6083                         disabledClasses = new ArraySet<>(changedClasses.length);
6084                     }
6085                     disabledClasses.add(changedClass);
6086                 }
6087             }
6088         }
6089
6090         if (!packageDisabled && disabledClasses == null) {
6091             // Nothing to do here...
6092             return;
6093         }
6094
6095         // Clean-up disabled activities.
6096         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6097                 packageName, disabledClasses, true, false, userId) && mBooted) {
6098             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6099             mStackSupervisor.scheduleIdleLocked();
6100         }
6101
6102         // Clean-up disabled tasks
6103         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6104
6105         // Clean-up disabled services.
6106         mServices.bringDownDisabledPackageServicesLocked(
6107                 packageName, disabledClasses, userId, false, killProcess, true);
6108
6109         // Clean-up disabled providers.
6110         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6111         mProviderMap.collectPackageProvidersLocked(
6112                 packageName, disabledClasses, true, false, userId, providers);
6113         for (int i = providers.size() - 1; i >= 0; i--) {
6114             removeDyingProviderLocked(null, providers.get(i), true);
6115         }
6116
6117         // Clean-up disabled broadcast receivers.
6118         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6119             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6120                     packageName, disabledClasses, userId, true);
6121         }
6122
6123     }
6124
6125     final boolean clearBroadcastQueueForUserLocked(int userId) {
6126         boolean didSomething = false;
6127         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6128             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6129                     null, null, userId, true);
6130         }
6131         return didSomething;
6132     }
6133
6134     final boolean forceStopPackageLocked(String packageName, int appId,
6135             boolean callerWillRestart, boolean purgeCache, boolean doit,
6136             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6137         int i;
6138
6139         if (userId == UserHandle.USER_ALL && packageName == null) {
6140             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6141         }
6142
6143         if (appId < 0 && packageName != null) {
6144             try {
6145                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6146                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6147             } catch (RemoteException e) {
6148             }
6149         }
6150
6151         if (doit) {
6152             if (packageName != null) {
6153                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6154                         + " user=" + userId + ": " + reason);
6155             } else {
6156                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6157             }
6158
6159             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6160         }
6161
6162         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6163                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6164                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6165
6166         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6167                 packageName, null, doit, evenPersistent, userId)) {
6168             if (!doit) {
6169                 return true;
6170             }
6171             didSomething = true;
6172         }
6173
6174         if (mServices.bringDownDisabledPackageServicesLocked(
6175                 packageName, null, userId, evenPersistent, true, doit)) {
6176             if (!doit) {
6177                 return true;
6178             }
6179             didSomething = true;
6180         }
6181
6182         if (packageName == null) {
6183             // Remove all sticky broadcasts from this user.
6184             mStickyBroadcasts.remove(userId);
6185         }
6186
6187         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6188         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6189                 userId, providers)) {
6190             if (!doit) {
6191                 return true;
6192             }
6193             didSomething = true;
6194         }
6195         for (i = providers.size() - 1; i >= 0; i--) {
6196             removeDyingProviderLocked(null, providers.get(i), true);
6197         }
6198
6199         // Remove transient permissions granted from/to this package/user
6200         removeUriPermissionsForPackageLocked(packageName, userId, false);
6201
6202         if (doit) {
6203             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6204                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6205                         packageName, null, userId, doit);
6206             }
6207         }
6208
6209         if (packageName == null || uninstalling) {
6210             // Remove pending intents.  For now we only do this when force
6211             // stopping users, because we have some problems when doing this
6212             // for packages -- app widgets are not currently cleaned up for
6213             // such packages, so they can be left with bad pending intents.
6214             if (mIntentSenderRecords.size() > 0) {
6215                 Iterator<WeakReference<PendingIntentRecord>> it
6216                         = mIntentSenderRecords.values().iterator();
6217                 while (it.hasNext()) {
6218                     WeakReference<PendingIntentRecord> wpir = it.next();
6219                     if (wpir == null) {
6220                         it.remove();
6221                         continue;
6222                     }
6223                     PendingIntentRecord pir = wpir.get();
6224                     if (pir == null) {
6225                         it.remove();
6226                         continue;
6227                     }
6228                     if (packageName == null) {
6229                         // Stopping user, remove all objects for the user.
6230                         if (pir.key.userId != userId) {
6231                             // Not the same user, skip it.
6232                             continue;
6233                         }
6234                     } else {
6235                         if (UserHandle.getAppId(pir.uid) != appId) {
6236                             // Different app id, skip it.
6237                             continue;
6238                         }
6239                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6240                             // Different user, skip it.
6241                             continue;
6242                         }
6243                         if (!pir.key.packageName.equals(packageName)) {
6244                             // Different package, skip it.
6245                             continue;
6246                         }
6247                     }
6248                     if (!doit) {
6249                         return true;
6250                     }
6251                     didSomething = true;
6252                     it.remove();
6253                     pir.canceled = true;
6254                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6255                         pir.key.activity.pendingResults.remove(pir.ref);
6256                     }
6257                 }
6258             }
6259         }
6260
6261         if (doit) {
6262             if (purgeCache && packageName != null) {
6263                 AttributeCache ac = AttributeCache.instance();
6264                 if (ac != null) {
6265                     ac.removePackage(packageName);
6266                 }
6267             }
6268             if (mBooted) {
6269                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6270                 mStackSupervisor.scheduleIdleLocked();
6271             }
6272         }
6273
6274         return didSomething;
6275     }
6276
6277     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6278         ProcessRecord old = mProcessNames.remove(name, uid);
6279         if (old != null) {
6280             old.uidRecord.numProcs--;
6281             if (old.uidRecord.numProcs == 0) {
6282                 // No more processes using this uid, tell clients it is gone.
6283                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6284                         "No more processes in " + old.uidRecord);
6285                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6286                 mActiveUids.remove(uid);
6287                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6288             }
6289             old.uidRecord = null;
6290         }
6291         mIsolatedProcesses.remove(uid);
6292         return old;
6293     }
6294
6295     private final void addProcessNameLocked(ProcessRecord proc) {
6296         // We shouldn't already have a process under this name, but just in case we
6297         // need to clean up whatever may be there now.
6298         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6299         if (old == proc && proc.persistent) {
6300             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6301             Slog.w(TAG, "Re-adding persistent process " + proc);
6302         } else if (old != null) {
6303             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6304         }
6305         UidRecord uidRec = mActiveUids.get(proc.uid);
6306         if (uidRec == null) {
6307             uidRec = new UidRecord(proc.uid);
6308             // This is the first appearance of the uid, report it now!
6309             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6310                     "Creating new process uid: " + uidRec);
6311             mActiveUids.put(proc.uid, uidRec);
6312             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6313             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6314         }
6315         proc.uidRecord = uidRec;
6316
6317         // Reset render thread tid if it was already set, so new process can set it again.
6318         proc.renderThreadTid = 0;
6319         uidRec.numProcs++;
6320         mProcessNames.put(proc.processName, proc.uid, proc);
6321         if (proc.isolated) {
6322             mIsolatedProcesses.put(proc.uid, proc);
6323         }
6324     }
6325
6326     boolean removeProcessLocked(ProcessRecord app,
6327             boolean callerWillRestart, boolean allowRestart, String reason) {
6328         final String name = app.processName;
6329         final int uid = app.uid;
6330         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6331             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6332
6333         ProcessRecord old = mProcessNames.get(name, uid);
6334         if (old != app) {
6335             // This process is no longer active, so nothing to do.
6336             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6337             return false;
6338         }
6339         removeProcessNameLocked(name, uid);
6340         if (mHeavyWeightProcess == app) {
6341             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6342                     mHeavyWeightProcess.userId, 0));
6343             mHeavyWeightProcess = null;
6344         }
6345         boolean needRestart = false;
6346         if (app.pid > 0 && app.pid != MY_PID) {
6347             int pid = app.pid;
6348             synchronized (mPidsSelfLocked) {
6349                 mPidsSelfLocked.remove(pid);
6350                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6351             }
6352             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6353             if (app.isolated) {
6354                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6355             }
6356             boolean willRestart = false;
6357             if (app.persistent && !app.isolated) {
6358                 if (!callerWillRestart) {
6359                     willRestart = true;
6360                 } else {
6361                     needRestart = true;
6362                 }
6363             }
6364             app.kill(reason, true);
6365             handleAppDiedLocked(app, willRestart, allowRestart);
6366             if (willRestart) {
6367                 removeLruProcessLocked(app);
6368                 addAppLocked(app.info, false, null /* ABI override */);
6369             }
6370         } else {
6371             mRemovedProcesses.add(app);
6372         }
6373
6374         return needRestart;
6375     }
6376
6377     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6378         cleanupAppInLaunchingProvidersLocked(app, true);
6379         removeProcessLocked(app, false, true, "timeout publishing content providers");
6380     }
6381
6382     private final void processStartTimedOutLocked(ProcessRecord app) {
6383         final int pid = app.pid;
6384         boolean gone = false;
6385         synchronized (mPidsSelfLocked) {
6386             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6387             if (knownApp != null && knownApp.thread == null) {
6388                 mPidsSelfLocked.remove(pid);
6389                 gone = true;
6390             }
6391         }
6392
6393         if (gone) {
6394             Slog.w(TAG, "Process " + app + " failed to attach");
6395             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6396                     pid, app.uid, app.processName);
6397             removeProcessNameLocked(app.processName, app.uid);
6398             if (mHeavyWeightProcess == app) {
6399                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6400                         mHeavyWeightProcess.userId, 0));
6401                 mHeavyWeightProcess = null;
6402             }
6403             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6404             if (app.isolated) {
6405                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6406             }
6407             // Take care of any launching providers waiting for this process.
6408             cleanupAppInLaunchingProvidersLocked(app, true);
6409             // Take care of any services that are waiting for the process.
6410             mServices.processStartTimedOutLocked(app);
6411             app.kill("start timeout", true);
6412             removeLruProcessLocked(app);
6413             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6414                 Slog.w(TAG, "Unattached app died before backup, skipping");
6415                 try {
6416                     IBackupManager bm = IBackupManager.Stub.asInterface(
6417                             ServiceManager.getService(Context.BACKUP_SERVICE));
6418                     bm.agentDisconnected(app.info.packageName);
6419                 } catch (RemoteException e) {
6420                     // Can't happen; the backup manager is local
6421                 }
6422             }
6423             if (isPendingBroadcastProcessLocked(pid)) {
6424                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6425                 skipPendingBroadcastLocked(pid);
6426             }
6427         } else {
6428             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6429         }
6430     }
6431
6432     private final boolean attachApplicationLocked(IApplicationThread thread,
6433             int pid) {
6434
6435         // Find the application record that is being attached...  either via
6436         // the pid if we are running in multiple processes, or just pull the
6437         // next app record if we are emulating process with anonymous threads.
6438         ProcessRecord app;
6439         if (pid != MY_PID && pid >= 0) {
6440             synchronized (mPidsSelfLocked) {
6441                 app = mPidsSelfLocked.get(pid);
6442             }
6443         } else {
6444             app = null;
6445         }
6446
6447         if (app == null) {
6448             Slog.w(TAG, "No pending application record for pid " + pid
6449                     + " (IApplicationThread " + thread + "); dropping process");
6450             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6451             if (pid > 0 && pid != MY_PID) {
6452                 Process.killProcessQuiet(pid);
6453                 //TODO: killProcessGroup(app.info.uid, pid);
6454             } else {
6455                 try {
6456                     thread.scheduleExit();
6457                 } catch (Exception e) {
6458                     // Ignore exceptions.
6459                 }
6460             }
6461             return false;
6462         }
6463
6464         // If this application record is still attached to a previous
6465         // process, clean it up now.
6466         if (app.thread != null) {
6467             handleAppDiedLocked(app, true, true);
6468         }
6469
6470         // Tell the process all about itself.
6471
6472         if (DEBUG_ALL) Slog.v(
6473                 TAG, "Binding process pid " + pid + " to record " + app);
6474
6475         final String processName = app.processName;
6476         try {
6477             AppDeathRecipient adr = new AppDeathRecipient(
6478                     app, pid, thread);
6479             thread.asBinder().linkToDeath(adr, 0);
6480             app.deathRecipient = adr;
6481         } catch (RemoteException e) {
6482             app.resetPackageList(mProcessStats);
6483             startProcessLocked(app, "link fail", processName);
6484             return false;
6485         }
6486
6487         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6488
6489         app.makeActive(thread, mProcessStats);
6490         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6491         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6492         app.forcingToForeground = null;
6493         updateProcessForegroundLocked(app, false, false);
6494         app.hasShownUi = false;
6495         app.debugging = false;
6496         app.cached = false;
6497         app.killedByAm = false;
6498
6499         // We carefully use the same state that PackageManager uses for
6500         // filtering, since we use this flag to decide if we need to install
6501         // providers when user is unlocked later
6502         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6503
6504         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6505
6506         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6507         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6508
6509         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6510             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6511             msg.obj = app;
6512             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6513         }
6514
6515         if (!normalMode) {
6516             Slog.i(TAG, "Launching preboot mode app: " + app);
6517         }
6518
6519         if (DEBUG_ALL) Slog.v(
6520             TAG, "New app record " + app
6521             + " thread=" + thread.asBinder() + " pid=" + pid);
6522         try {
6523             int testMode = IApplicationThread.DEBUG_OFF;
6524             if (mDebugApp != null && mDebugApp.equals(processName)) {
6525                 testMode = mWaitForDebugger
6526                     ? IApplicationThread.DEBUG_WAIT
6527                     : IApplicationThread.DEBUG_ON;
6528                 app.debugging = true;
6529                 if (mDebugTransient) {
6530                     mDebugApp = mOrigDebugApp;
6531                     mWaitForDebugger = mOrigWaitForDebugger;
6532                 }
6533             }
6534             String profileFile = app.instrumentationProfileFile;
6535             ParcelFileDescriptor profileFd = null;
6536             int samplingInterval = 0;
6537             boolean profileAutoStop = false;
6538             if (mProfileApp != null && mProfileApp.equals(processName)) {
6539                 mProfileProc = app;
6540                 profileFile = mProfileFile;
6541                 profileFd = mProfileFd;
6542                 samplingInterval = mSamplingInterval;
6543                 profileAutoStop = mAutoStopProfiler;
6544             }
6545             boolean enableTrackAllocation = false;
6546             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6547                 enableTrackAllocation = true;
6548                 mTrackAllocationApp = null;
6549             }
6550
6551             // If the app is being launched for restore or full backup, set it up specially
6552             boolean isRestrictedBackupMode = false;
6553             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6554                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6555                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6556                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6557                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6558             }
6559
6560             if (app.instrumentationClass != null) {
6561                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6562                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6563             }
6564             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6565                     + processName + " with config " + mConfiguration);
6566             ApplicationInfo appInfo = app.instrumentationInfo != null
6567                     ? app.instrumentationInfo : app.info;
6568             app.compat = compatibilityInfoForPackageLocked(appInfo);
6569             if (profileFd != null) {
6570                 profileFd = profileFd.dup();
6571             }
6572             ProfilerInfo profilerInfo = profileFile == null ? null
6573                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6574             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6575                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6576                     app.instrumentationUiAutomationConnection, testMode,
6577                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6578                     isRestrictedBackupMode || !normalMode, app.persistent,
6579                     new Configuration(mConfiguration), app.compat,
6580                     getCommonServicesLocked(app.isolated),
6581                     mCoreSettingsObserver.getCoreSettingsLocked());
6582             updateLruProcessLocked(app, false, null);
6583             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6584         } catch (Exception e) {
6585             // todo: Yikes!  What should we do?  For now we will try to
6586             // start another process, but that could easily get us in
6587             // an infinite loop of restarting processes...
6588             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6589
6590             app.resetPackageList(mProcessStats);
6591             app.unlinkDeathRecipient();
6592             startProcessLocked(app, "bind fail", processName);
6593             return false;
6594         }
6595
6596         // Remove this record from the list of starting applications.
6597         mPersistentStartingProcesses.remove(app);
6598         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6599                 "Attach application locked removing on hold: " + app);
6600         mProcessesOnHold.remove(app);
6601
6602         boolean badApp = false;
6603         boolean didSomething = false;
6604
6605         // See if the top visible activity is waiting to run in this process...
6606         if (normalMode) {
6607             try {
6608                 if (mStackSupervisor.attachApplicationLocked(app)) {
6609                     didSomething = true;
6610                 }
6611             } catch (Exception e) {
6612                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6613                 badApp = true;
6614             }
6615         }
6616
6617         // Find any services that should be running in this process...
6618         if (!badApp) {
6619             try {
6620                 didSomething |= mServices.attachApplicationLocked(app, processName);
6621             } catch (Exception e) {
6622                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6623                 badApp = true;
6624             }
6625         }
6626
6627         // Check if a next-broadcast receiver is in this process...
6628         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6629             try {
6630                 didSomething |= sendPendingBroadcastsLocked(app);
6631             } catch (Exception e) {
6632                 // If the app died trying to launch the receiver we declare it 'bad'
6633                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6634                 badApp = true;
6635             }
6636         }
6637
6638         // Check whether the next backup agent is in this process...
6639         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6640             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6641                     "New app is backup target, launching agent for " + app);
6642             notifyPackageUse(mBackupTarget.appInfo.packageName,
6643                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6644             try {
6645                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6646                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6647                         mBackupTarget.backupMode);
6648             } catch (Exception e) {
6649                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6650                 badApp = true;
6651             }
6652         }
6653
6654         if (badApp) {
6655             app.kill("error during init", true);
6656             handleAppDiedLocked(app, false, true);
6657             return false;
6658         }
6659
6660         if (!didSomething) {
6661             updateOomAdjLocked();
6662         }
6663
6664         return true;
6665     }
6666
6667     @Override
6668     public final void attachApplication(IApplicationThread thread) {
6669         synchronized (this) {
6670             int callingPid = Binder.getCallingPid();
6671             final long origId = Binder.clearCallingIdentity();
6672             attachApplicationLocked(thread, callingPid);
6673             Binder.restoreCallingIdentity(origId);
6674         }
6675     }
6676
6677     @Override
6678     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6679         final long origId = Binder.clearCallingIdentity();
6680         synchronized (this) {
6681             ActivityStack stack = ActivityRecord.getStackLocked(token);
6682             if (stack != null) {
6683                 ActivityRecord r =
6684                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6685                 if (stopProfiling) {
6686                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6687                         try {
6688                             mProfileFd.close();
6689                         } catch (IOException e) {
6690                         }
6691                         clearProfilerLocked();
6692                     }
6693                 }
6694             }
6695         }
6696         Binder.restoreCallingIdentity(origId);
6697     }
6698
6699     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6700         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6701                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6702     }
6703
6704     void enableScreenAfterBoot() {
6705         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6706                 SystemClock.uptimeMillis());
6707         mWindowManager.enableScreenAfterBoot();
6708
6709         synchronized (this) {
6710             updateEventDispatchingLocked();
6711         }
6712     }
6713
6714     @Override
6715     public void showBootMessage(final CharSequence msg, final boolean always) {
6716         if (Binder.getCallingUid() != Process.myUid()) {
6717             throw new SecurityException();
6718         }
6719         mWindowManager.showBootMessage(msg, always);
6720     }
6721
6722     @Override
6723     public void keyguardWaitingForActivityDrawn() {
6724         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6725         final long token = Binder.clearCallingIdentity();
6726         try {
6727             synchronized (this) {
6728                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6729                 mWindowManager.keyguardWaitingForActivityDrawn();
6730                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6731                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6732                     updateSleepIfNeededLocked();
6733                 }
6734             }
6735         } finally {
6736             Binder.restoreCallingIdentity(token);
6737         }
6738     }
6739
6740     @Override
6741     public void keyguardGoingAway(int flags) {
6742         enforceNotIsolatedCaller("keyguardGoingAway");
6743         final long token = Binder.clearCallingIdentity();
6744         try {
6745             synchronized (this) {
6746                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6747                 mWindowManager.keyguardGoingAway(flags);
6748                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6749                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6750                     updateSleepIfNeededLocked();
6751
6752                     // Some stack visibility might change (e.g. docked stack)
6753                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6754                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6755                 }
6756             }
6757         } finally {
6758             Binder.restoreCallingIdentity(token);
6759         }
6760     }
6761
6762     final void finishBooting() {
6763         synchronized (this) {
6764             if (!mBootAnimationComplete) {
6765                 mCallFinishBooting = true;
6766                 return;
6767             }
6768             mCallFinishBooting = false;
6769         }
6770
6771         ArraySet<String> completedIsas = new ArraySet<String>();
6772         for (String abi : Build.SUPPORTED_ABIS) {
6773             Process.establishZygoteConnectionForAbi(abi);
6774             final String instructionSet = VMRuntime.getInstructionSet(abi);
6775             if (!completedIsas.contains(instructionSet)) {
6776                 try {
6777                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6778                 } catch (InstallerException e) {
6779                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6780                             e.getMessage() +")");
6781                 }
6782                 completedIsas.add(instructionSet);
6783             }
6784         }
6785
6786         IntentFilter pkgFilter = new IntentFilter();
6787         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6788         pkgFilter.addDataScheme("package");
6789         mContext.registerReceiver(new BroadcastReceiver() {
6790             @Override
6791             public void onReceive(Context context, Intent intent) {
6792                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6793                 if (pkgs != null) {
6794                     for (String pkg : pkgs) {
6795                         synchronized (ActivityManagerService.this) {
6796                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6797                                     0, "query restart")) {
6798                                 setResultCode(Activity.RESULT_OK);
6799                                 return;
6800                             }
6801                         }
6802                     }
6803                 }
6804             }
6805         }, pkgFilter);
6806
6807         IntentFilter dumpheapFilter = new IntentFilter();
6808         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6809         mContext.registerReceiver(new BroadcastReceiver() {
6810             @Override
6811             public void onReceive(Context context, Intent intent) {
6812                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6813                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6814                 } else {
6815                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6816                 }
6817             }
6818         }, dumpheapFilter);
6819
6820         // Let system services know.
6821         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6822
6823         synchronized (this) {
6824             // Ensure that any processes we had put on hold are now started
6825             // up.
6826             final int NP = mProcessesOnHold.size();
6827             if (NP > 0) {
6828                 ArrayList<ProcessRecord> procs =
6829                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6830                 for (int ip=0; ip<NP; ip++) {
6831                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6832                             + procs.get(ip));
6833                     startProcessLocked(procs.get(ip), "on-hold", null);
6834                 }
6835             }
6836
6837             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6838                 // Start looking for apps that are abusing wake locks.
6839                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6840                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6841                 // Tell anyone interested that we are done booting!
6842                 SystemProperties.set("sys.boot_completed", "1");
6843
6844                 // And trigger dev.bootcomplete if we are not showing encryption progress
6845                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6846                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6847                     SystemProperties.set("dev.bootcomplete", "1");
6848                 }
6849                 mUserController.sendBootCompletedLocked(
6850                         new IIntentReceiver.Stub() {
6851                             @Override
6852                             public void performReceive(Intent intent, int resultCode,
6853                                     String data, Bundle extras, boolean ordered,
6854                                     boolean sticky, int sendingUser) {
6855                                 synchronized (ActivityManagerService.this) {
6856                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6857                                             true, false);
6858                                 }
6859                             }
6860                         });
6861                 scheduleStartProfilesLocked();
6862             }
6863         }
6864     }
6865
6866     @Override
6867     public void bootAnimationComplete() {
6868         final boolean callFinishBooting;
6869         synchronized (this) {
6870             callFinishBooting = mCallFinishBooting;
6871             mBootAnimationComplete = true;
6872         }
6873         if (callFinishBooting) {
6874             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6875             finishBooting();
6876             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6877         }
6878     }
6879
6880     final void ensureBootCompleted() {
6881         boolean booting;
6882         boolean enableScreen;
6883         synchronized (this) {
6884             booting = mBooting;
6885             mBooting = false;
6886             enableScreen = !mBooted;
6887             mBooted = true;
6888         }
6889
6890         if (booting) {
6891             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6892             finishBooting();
6893             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6894         }
6895
6896         if (enableScreen) {
6897             enableScreenAfterBoot();
6898         }
6899     }
6900
6901     @Override
6902     public final void activityResumed(IBinder token) {
6903         final long origId = Binder.clearCallingIdentity();
6904         synchronized(this) {
6905             ActivityStack stack = ActivityRecord.getStackLocked(token);
6906             if (stack != null) {
6907                 stack.activityResumedLocked(token);
6908             }
6909         }
6910         Binder.restoreCallingIdentity(origId);
6911     }
6912
6913     @Override
6914     public final void activityPaused(IBinder token) {
6915         final long origId = Binder.clearCallingIdentity();
6916         synchronized(this) {
6917             ActivityStack stack = ActivityRecord.getStackLocked(token);
6918             if (stack != null) {
6919                 stack.activityPausedLocked(token, false);
6920             }
6921         }
6922         Binder.restoreCallingIdentity(origId);
6923     }
6924
6925     @Override
6926     public final void activityStopped(IBinder token, Bundle icicle,
6927             PersistableBundle persistentState, CharSequence description) {
6928         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6929
6930         // Refuse possible leaked file descriptors
6931         if (icicle != null && icicle.hasFileDescriptors()) {
6932             throw new IllegalArgumentException("File descriptors passed in Bundle");
6933         }
6934
6935         final long origId = Binder.clearCallingIdentity();
6936
6937         synchronized (this) {
6938             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6939             if (r != null) {
6940                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6941             }
6942         }
6943
6944         trimApplications();
6945
6946         Binder.restoreCallingIdentity(origId);
6947     }
6948
6949     @Override
6950     public final void activityDestroyed(IBinder token) {
6951         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6952         synchronized (this) {
6953             ActivityStack stack = ActivityRecord.getStackLocked(token);
6954             if (stack != null) {
6955                 stack.activityDestroyedLocked(token, "activityDestroyed");
6956             }
6957         }
6958     }
6959
6960     @Override
6961     public final void activityRelaunched(IBinder token) {
6962         final long origId = Binder.clearCallingIdentity();
6963         synchronized (this) {
6964             mStackSupervisor.activityRelaunchedLocked(token);
6965         }
6966         Binder.restoreCallingIdentity(origId);
6967     }
6968
6969     @Override
6970     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6971             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6972         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6973                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6974         synchronized (this) {
6975             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6976             if (record == null) {
6977                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6978                         + "found for: " + token);
6979             }
6980             record.setSizeConfigurations(horizontalSizeConfiguration,
6981                     verticalSizeConfigurations, smallestSizeConfigurations);
6982         }
6983     }
6984
6985     @Override
6986     public final void backgroundResourcesReleased(IBinder token) {
6987         final long origId = Binder.clearCallingIdentity();
6988         try {
6989             synchronized (this) {
6990                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6991                 if (stack != null) {
6992                     stack.backgroundResourcesReleased();
6993                 }
6994             }
6995         } finally {
6996             Binder.restoreCallingIdentity(origId);
6997         }
6998     }
6999
7000     @Override
7001     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7002         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7003     }
7004
7005     @Override
7006     public final void notifyEnterAnimationComplete(IBinder token) {
7007         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7008     }
7009
7010     @Override
7011     public String getCallingPackage(IBinder token) {
7012         synchronized (this) {
7013             ActivityRecord r = getCallingRecordLocked(token);
7014             return r != null ? r.info.packageName : null;
7015         }
7016     }
7017
7018     @Override
7019     public ComponentName getCallingActivity(IBinder token) {
7020         synchronized (this) {
7021             ActivityRecord r = getCallingRecordLocked(token);
7022             return r != null ? r.intent.getComponent() : null;
7023         }
7024     }
7025
7026     private ActivityRecord getCallingRecordLocked(IBinder token) {
7027         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7028         if (r == null) {
7029             return null;
7030         }
7031         return r.resultTo;
7032     }
7033
7034     @Override
7035     public ComponentName getActivityClassForToken(IBinder token) {
7036         synchronized(this) {
7037             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7038             if (r == null) {
7039                 return null;
7040             }
7041             return r.intent.getComponent();
7042         }
7043     }
7044
7045     @Override
7046     public String getPackageForToken(IBinder token) {
7047         synchronized(this) {
7048             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7049             if (r == null) {
7050                 return null;
7051             }
7052             return r.packageName;
7053         }
7054     }
7055
7056     @Override
7057     public boolean isRootVoiceInteraction(IBinder token) {
7058         synchronized(this) {
7059             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7060             if (r == null) {
7061                 return false;
7062             }
7063             return r.rootVoiceInteraction;
7064         }
7065     }
7066
7067     @Override
7068     public IIntentSender getIntentSender(int type,
7069             String packageName, IBinder token, String resultWho,
7070             int requestCode, Intent[] intents, String[] resolvedTypes,
7071             int flags, Bundle bOptions, int userId) {
7072         enforceNotIsolatedCaller("getIntentSender");
7073         // Refuse possible leaked file descriptors
7074         if (intents != null) {
7075             if (intents.length < 1) {
7076                 throw new IllegalArgumentException("Intents array length must be >= 1");
7077             }
7078             for (int i=0; i<intents.length; i++) {
7079                 Intent intent = intents[i];
7080                 if (intent != null) {
7081                     if (intent.hasFileDescriptors()) {
7082                         throw new IllegalArgumentException("File descriptors passed in Intent");
7083                     }
7084                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7085                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7086                         throw new IllegalArgumentException(
7087                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7088                     }
7089                     intents[i] = new Intent(intent);
7090                 }
7091             }
7092             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7093                 throw new IllegalArgumentException(
7094                         "Intent array length does not match resolvedTypes length");
7095             }
7096         }
7097         if (bOptions != null) {
7098             if (bOptions.hasFileDescriptors()) {
7099                 throw new IllegalArgumentException("File descriptors passed in options");
7100             }
7101         }
7102
7103         synchronized(this) {
7104             int callingUid = Binder.getCallingUid();
7105             int origUserId = userId;
7106             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7107                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7108                     ALLOW_NON_FULL, "getIntentSender", null);
7109             if (origUserId == UserHandle.USER_CURRENT) {
7110                 // We don't want to evaluate this until the pending intent is
7111                 // actually executed.  However, we do want to always do the
7112                 // security checking for it above.
7113                 userId = UserHandle.USER_CURRENT;
7114             }
7115             try {
7116                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7117                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7118                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7119                     if (!UserHandle.isSameApp(callingUid, uid)) {
7120                         String msg = "Permission Denial: getIntentSender() from pid="
7121                             + Binder.getCallingPid()
7122                             + ", uid=" + Binder.getCallingUid()
7123                             + ", (need uid=" + uid + ")"
7124                             + " is not allowed to send as package " + packageName;
7125                         Slog.w(TAG, msg);
7126                         throw new SecurityException(msg);
7127                     }
7128                 }
7129
7130                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7131                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7132
7133             } catch (RemoteException e) {
7134                 throw new SecurityException(e);
7135             }
7136         }
7137     }
7138
7139     IIntentSender getIntentSenderLocked(int type, String packageName,
7140             int callingUid, int userId, IBinder token, String resultWho,
7141             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7142             Bundle bOptions) {
7143         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7144         ActivityRecord activity = null;
7145         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7146             activity = ActivityRecord.isInStackLocked(token);
7147             if (activity == null) {
7148                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7149                 return null;
7150             }
7151             if (activity.finishing) {
7152                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7153                 return null;
7154             }
7155         }
7156
7157         // We're going to be splicing together extras before sending, so we're
7158         // okay poking into any contained extras.
7159         if (intents != null) {
7160             for (int i = 0; i < intents.length; i++) {
7161                 intents[i].setDefusable(true);
7162             }
7163         }
7164         Bundle.setDefusable(bOptions, true);
7165
7166         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7167         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7168         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7169         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7170                 |PendingIntent.FLAG_UPDATE_CURRENT);
7171
7172         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7173                 type, packageName, activity, resultWho,
7174                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7175         WeakReference<PendingIntentRecord> ref;
7176         ref = mIntentSenderRecords.get(key);
7177         PendingIntentRecord rec = ref != null ? ref.get() : null;
7178         if (rec != null) {
7179             if (!cancelCurrent) {
7180                 if (updateCurrent) {
7181                     if (rec.key.requestIntent != null) {
7182                         rec.key.requestIntent.replaceExtras(intents != null ?
7183                                 intents[intents.length - 1] : null);
7184                     }
7185                     if (intents != null) {
7186                         intents[intents.length-1] = rec.key.requestIntent;
7187                         rec.key.allIntents = intents;
7188                         rec.key.allResolvedTypes = resolvedTypes;
7189                     } else {
7190                         rec.key.allIntents = null;
7191                         rec.key.allResolvedTypes = null;
7192                     }
7193                 }
7194                 return rec;
7195             }
7196             rec.canceled = true;
7197             mIntentSenderRecords.remove(key);
7198         }
7199         if (noCreate) {
7200             return rec;
7201         }
7202         rec = new PendingIntentRecord(this, key, callingUid);
7203         mIntentSenderRecords.put(key, rec.ref);
7204         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7205             if (activity.pendingResults == null) {
7206                 activity.pendingResults
7207                         = new HashSet<WeakReference<PendingIntentRecord>>();
7208             }
7209             activity.pendingResults.add(rec.ref);
7210         }
7211         return rec;
7212     }
7213
7214     @Override
7215     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7216             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7217         if (target instanceof PendingIntentRecord) {
7218             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7219                     finishedReceiver, requiredPermission, options);
7220         } else {
7221             if (intent == null) {
7222                 // Weird case: someone has given us their own custom IIntentSender, and now
7223                 // they have someone else trying to send to it but of course this isn't
7224                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7225                 // supplying an Intent... but we never want to dispatch a null Intent to
7226                 // a receiver, so um...  let's make something up.
7227                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7228                 intent = new Intent(Intent.ACTION_MAIN);
7229             }
7230             try {
7231                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7232             } catch (RemoteException e) {
7233             }
7234             // Platform code can rely on getting a result back when the send is done, but if
7235             // this intent sender is from outside of the system we can't rely on it doing that.
7236             // So instead we don't give it the result receiver, and instead just directly
7237             // report the finish immediately.
7238             if (finishedReceiver != null) {
7239                 try {
7240                     finishedReceiver.performReceive(intent, 0,
7241                             null, null, false, false, UserHandle.getCallingUserId());
7242                 } catch (RemoteException e) {
7243                 }
7244             }
7245             return 0;
7246         }
7247     }
7248
7249     /**
7250      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7251      *
7252      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7253      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7254      */
7255     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7256         if (DEBUG_WHITELISTS) {
7257             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7258                     + targetUid + ", " + duration + ")");
7259         }
7260         synchronized (mPidsSelfLocked) {
7261             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7262             if (pr == null) {
7263                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7264                 return;
7265             }
7266             if (!pr.whitelistManager) {
7267                 if (DEBUG_WHITELISTS) {
7268                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7269                             + callerPid + " is not allowed");
7270                 }
7271                 return;
7272             }
7273         }
7274
7275         final long token = Binder.clearCallingIdentity();
7276         try {
7277             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7278                     true, "pe from uid:" + callerUid);
7279         } finally {
7280             Binder.restoreCallingIdentity(token);
7281         }
7282     }
7283
7284     @Override
7285     public void cancelIntentSender(IIntentSender sender) {
7286         if (!(sender instanceof PendingIntentRecord)) {
7287             return;
7288         }
7289         synchronized(this) {
7290             PendingIntentRecord rec = (PendingIntentRecord)sender;
7291             try {
7292                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7293                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7294                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7295                     String msg = "Permission Denial: cancelIntentSender() from pid="
7296                         + Binder.getCallingPid()
7297                         + ", uid=" + Binder.getCallingUid()
7298                         + " is not allowed to cancel packges "
7299                         + rec.key.packageName;
7300                     Slog.w(TAG, msg);
7301                     throw new SecurityException(msg);
7302                 }
7303             } catch (RemoteException e) {
7304                 throw new SecurityException(e);
7305             }
7306             cancelIntentSenderLocked(rec, true);
7307         }
7308     }
7309
7310     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7311         rec.canceled = true;
7312         mIntentSenderRecords.remove(rec.key);
7313         if (cleanActivity && rec.key.activity != null) {
7314             rec.key.activity.pendingResults.remove(rec.ref);
7315         }
7316     }
7317
7318     @Override
7319     public String getPackageForIntentSender(IIntentSender pendingResult) {
7320         if (!(pendingResult instanceof PendingIntentRecord)) {
7321             return null;
7322         }
7323         try {
7324             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7325             return res.key.packageName;
7326         } catch (ClassCastException e) {
7327         }
7328         return null;
7329     }
7330
7331     @Override
7332     public int getUidForIntentSender(IIntentSender sender) {
7333         if (sender instanceof PendingIntentRecord) {
7334             try {
7335                 PendingIntentRecord res = (PendingIntentRecord)sender;
7336                 return res.uid;
7337             } catch (ClassCastException e) {
7338             }
7339         }
7340         return -1;
7341     }
7342
7343     @Override
7344     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7345         if (!(pendingResult instanceof PendingIntentRecord)) {
7346             return false;
7347         }
7348         try {
7349             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7350             if (res.key.allIntents == null) {
7351                 return false;
7352             }
7353             for (int i=0; i<res.key.allIntents.length; i++) {
7354                 Intent intent = res.key.allIntents[i];
7355                 if (intent.getPackage() != null && intent.getComponent() != null) {
7356                     return false;
7357                 }
7358             }
7359             return true;
7360         } catch (ClassCastException e) {
7361         }
7362         return false;
7363     }
7364
7365     @Override
7366     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7367         if (!(pendingResult instanceof PendingIntentRecord)) {
7368             return false;
7369         }
7370         try {
7371             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7372             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7373                 return true;
7374             }
7375             return false;
7376         } catch (ClassCastException e) {
7377         }
7378         return false;
7379     }
7380
7381     @Override
7382     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7383         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7384                 "getIntentForIntentSender()");
7385         if (!(pendingResult instanceof PendingIntentRecord)) {
7386             return null;
7387         }
7388         try {
7389             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7390             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7391         } catch (ClassCastException e) {
7392         }
7393         return null;
7394     }
7395
7396     @Override
7397     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7398         if (!(pendingResult instanceof PendingIntentRecord)) {
7399             return null;
7400         }
7401         try {
7402             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7403             synchronized (this) {
7404                 return getTagForIntentSenderLocked(res, prefix);
7405             }
7406         } catch (ClassCastException e) {
7407         }
7408         return null;
7409     }
7410
7411     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7412         final Intent intent = res.key.requestIntent;
7413         if (intent != null) {
7414             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7415                     || res.lastTagPrefix.equals(prefix))) {
7416                 return res.lastTag;
7417             }
7418             res.lastTagPrefix = prefix;
7419             final StringBuilder sb = new StringBuilder(128);
7420             if (prefix != null) {
7421                 sb.append(prefix);
7422             }
7423             if (intent.getAction() != null) {
7424                 sb.append(intent.getAction());
7425             } else if (intent.getComponent() != null) {
7426                 intent.getComponent().appendShortString(sb);
7427             } else {
7428                 sb.append("?");
7429             }
7430             return res.lastTag = sb.toString();
7431         }
7432         return null;
7433     }
7434
7435     @Override
7436     public void setProcessLimit(int max) {
7437         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7438                 "setProcessLimit()");
7439         synchronized (this) {
7440             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7441             mProcessLimitOverride = max;
7442         }
7443         trimApplications();
7444     }
7445
7446     @Override
7447     public int getProcessLimit() {
7448         synchronized (this) {
7449             return mProcessLimitOverride;
7450         }
7451     }
7452
7453     void foregroundTokenDied(ForegroundToken token) {
7454         synchronized (ActivityManagerService.this) {
7455             synchronized (mPidsSelfLocked) {
7456                 ForegroundToken cur
7457                     = mForegroundProcesses.get(token.pid);
7458                 if (cur != token) {
7459                     return;
7460                 }
7461                 mForegroundProcesses.remove(token.pid);
7462                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7463                 if (pr == null) {
7464                     return;
7465                 }
7466                 pr.forcingToForeground = null;
7467                 updateProcessForegroundLocked(pr, false, false);
7468             }
7469             updateOomAdjLocked();
7470         }
7471     }
7472
7473     @Override
7474     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7475         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7476                 "setProcessForeground()");
7477         synchronized(this) {
7478             boolean changed = false;
7479
7480             synchronized (mPidsSelfLocked) {
7481                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7482                 if (pr == null && isForeground) {
7483                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7484                     return;
7485                 }
7486                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7487                 if (oldToken != null) {
7488                     oldToken.token.unlinkToDeath(oldToken, 0);
7489                     mForegroundProcesses.remove(pid);
7490                     if (pr != null) {
7491                         pr.forcingToForeground = null;
7492                     }
7493                     changed = true;
7494                 }
7495                 if (isForeground && token != null) {
7496                     ForegroundToken newToken = new ForegroundToken() {
7497                         @Override
7498                         public void binderDied() {
7499                             foregroundTokenDied(this);
7500                         }
7501                     };
7502                     newToken.pid = pid;
7503                     newToken.token = token;
7504                     try {
7505                         token.linkToDeath(newToken, 0);
7506                         mForegroundProcesses.put(pid, newToken);
7507                         pr.forcingToForeground = token;
7508                         changed = true;
7509                     } catch (RemoteException e) {
7510                         // If the process died while doing this, we will later
7511                         // do the cleanup with the process death link.
7512                     }
7513                 }
7514             }
7515
7516             if (changed) {
7517                 updateOomAdjLocked();
7518             }
7519         }
7520     }
7521
7522     @Override
7523     public boolean isAppForeground(int uid) throws RemoteException {
7524         synchronized (this) {
7525             UidRecord uidRec = mActiveUids.get(uid);
7526             if (uidRec == null || uidRec.idle) {
7527                 return false;
7528             }
7529             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7530         }
7531     }
7532
7533     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7534     // be guarded by permission checking.
7535     int getUidState(int uid) {
7536         synchronized (this) {
7537             UidRecord uidRec = mActiveUids.get(uid);
7538             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7539         }
7540     }
7541
7542     @Override
7543     public boolean isInMultiWindowMode(IBinder token) {
7544         final long origId = Binder.clearCallingIdentity();
7545         try {
7546             synchronized(this) {
7547                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7548                 if (r == null) {
7549                     return false;
7550                 }
7551                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7552                 return !r.task.mFullscreen;
7553             }
7554         } finally {
7555             Binder.restoreCallingIdentity(origId);
7556         }
7557     }
7558
7559     @Override
7560     public boolean isInPictureInPictureMode(IBinder token) {
7561         final long origId = Binder.clearCallingIdentity();
7562         try {
7563             synchronized(this) {
7564                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7565                 if (stack == null) {
7566                     return false;
7567                 }
7568                 return stack.mStackId == PINNED_STACK_ID;
7569             }
7570         } finally {
7571             Binder.restoreCallingIdentity(origId);
7572         }
7573     }
7574
7575     @Override
7576     public void enterPictureInPictureMode(IBinder token) {
7577         final long origId = Binder.clearCallingIdentity();
7578         try {
7579             synchronized(this) {
7580                 if (!mSupportsPictureInPicture) {
7581                     throw new IllegalStateException("enterPictureInPictureMode: "
7582                             + "Device doesn't support picture-in-picture mode.");
7583                 }
7584
7585                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7586
7587                 if (r == null) {
7588                     throw new IllegalStateException("enterPictureInPictureMode: "
7589                             + "Can't find activity for token=" + token);
7590                 }
7591
7592                 if (!r.supportsPictureInPicture()) {
7593                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7594                             + "Picture-In-Picture not supported for r=" + r);
7595                 }
7596
7597                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7598                 // current bounds.
7599                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7600                 final Rect bounds = (pinnedStack != null)
7601                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7602
7603                 mStackSupervisor.moveActivityToPinnedStackLocked(
7604                         r, "enterPictureInPictureMode", bounds);
7605             }
7606         } finally {
7607             Binder.restoreCallingIdentity(origId);
7608         }
7609     }
7610
7611     // =========================================================
7612     // PROCESS INFO
7613     // =========================================================
7614
7615     static class ProcessInfoService extends IProcessInfoService.Stub {
7616         final ActivityManagerService mActivityManagerService;
7617         ProcessInfoService(ActivityManagerService activityManagerService) {
7618             mActivityManagerService = activityManagerService;
7619         }
7620
7621         @Override
7622         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7623             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7624                     /*in*/ pids, /*out*/ states, null);
7625         }
7626
7627         @Override
7628         public void getProcessStatesAndOomScoresFromPids(
7629                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7630             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7631                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7632         }
7633     }
7634
7635     /**
7636      * For each PID in the given input array, write the current process state
7637      * for that process into the states array, or -1 to indicate that no
7638      * process with the given PID exists. If scores array is provided, write
7639      * the oom score for the process into the scores array, with INVALID_ADJ
7640      * indicating the PID doesn't exist.
7641      */
7642     public void getProcessStatesAndOomScoresForPIDs(
7643             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7644         if (scores != null) {
7645             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7646                     "getProcessStatesAndOomScoresForPIDs()");
7647         }
7648
7649         if (pids == null) {
7650             throw new NullPointerException("pids");
7651         } else if (states == null) {
7652             throw new NullPointerException("states");
7653         } else if (pids.length != states.length) {
7654             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7655         } else if (scores != null && pids.length != scores.length) {
7656             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7657         }
7658
7659         synchronized (mPidsSelfLocked) {
7660             for (int i = 0; i < pids.length; i++) {
7661                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7662                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7663                         pr.curProcState;
7664                 if (scores != null) {
7665                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7666                 }
7667             }
7668         }
7669     }
7670
7671     // =========================================================
7672     // PERMISSIONS
7673     // =========================================================
7674
7675     static class PermissionController extends IPermissionController.Stub {
7676         ActivityManagerService mActivityManagerService;
7677         PermissionController(ActivityManagerService activityManagerService) {
7678             mActivityManagerService = activityManagerService;
7679         }
7680
7681         @Override
7682         public boolean checkPermission(String permission, int pid, int uid) {
7683             return mActivityManagerService.checkPermission(permission, pid,
7684                     uid) == PackageManager.PERMISSION_GRANTED;
7685         }
7686
7687         @Override
7688         public String[] getPackagesForUid(int uid) {
7689             return mActivityManagerService.mContext.getPackageManager()
7690                     .getPackagesForUid(uid);
7691         }
7692
7693         @Override
7694         public boolean isRuntimePermission(String permission) {
7695             try {
7696                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7697                         .getPermissionInfo(permission, 0);
7698                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7699             } catch (NameNotFoundException nnfe) {
7700                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7701             }
7702             return false;
7703         }
7704     }
7705
7706     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7707         @Override
7708         public int checkComponentPermission(String permission, int pid, int uid,
7709                 int owningUid, boolean exported) {
7710             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7711                     owningUid, exported);
7712         }
7713
7714         @Override
7715         public Object getAMSLock() {
7716             return ActivityManagerService.this;
7717         }
7718     }
7719
7720     /**
7721      * This can be called with or without the global lock held.
7722      */
7723     int checkComponentPermission(String permission, int pid, int uid,
7724             int owningUid, boolean exported) {
7725         if (pid == MY_PID) {
7726             return PackageManager.PERMISSION_GRANTED;
7727         }
7728         return ActivityManager.checkComponentPermission(permission, uid,
7729                 owningUid, exported);
7730     }
7731
7732     /**
7733      * As the only public entry point for permissions checking, this method
7734      * can enforce the semantic that requesting a check on a null global
7735      * permission is automatically denied.  (Internally a null permission
7736      * string is used when calling {@link #checkComponentPermission} in cases
7737      * when only uid-based security is needed.)
7738      *
7739      * This can be called with or without the global lock held.
7740      */
7741     @Override
7742     public int checkPermission(String permission, int pid, int uid) {
7743         if (permission == null) {
7744             return PackageManager.PERMISSION_DENIED;
7745         }
7746         return checkComponentPermission(permission, pid, uid, -1, true);
7747     }
7748
7749     @Override
7750     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7751         if (permission == null) {
7752             return PackageManager.PERMISSION_DENIED;
7753         }
7754
7755         // We might be performing an operation on behalf of an indirect binder
7756         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7757         // client identity accordingly before proceeding.
7758         Identity tlsIdentity = sCallerIdentity.get();
7759         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7760             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7761                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7762             uid = tlsIdentity.uid;
7763             pid = tlsIdentity.pid;
7764         }
7765
7766         return checkComponentPermission(permission, pid, uid, -1, true);
7767     }
7768
7769     /**
7770      * Binder IPC calls go through the public entry point.
7771      * This can be called with or without the global lock held.
7772      */
7773     int checkCallingPermission(String permission) {
7774         return checkPermission(permission,
7775                 Binder.getCallingPid(),
7776                 UserHandle.getAppId(Binder.getCallingUid()));
7777     }
7778
7779     /**
7780      * This can be called with or without the global lock held.
7781      */
7782     void enforceCallingPermission(String permission, String func) {
7783         if (checkCallingPermission(permission)
7784                 == PackageManager.PERMISSION_GRANTED) {
7785             return;
7786         }
7787
7788         String msg = "Permission Denial: " + func + " from pid="
7789                 + Binder.getCallingPid()
7790                 + ", uid=" + Binder.getCallingUid()
7791                 + " requires " + permission;
7792         Slog.w(TAG, msg);
7793         throw new SecurityException(msg);
7794     }
7795
7796     /**
7797      * Determine if UID is holding permissions required to access {@link Uri} in
7798      * the given {@link ProviderInfo}. Final permission checking is always done
7799      * in {@link ContentProvider}.
7800      */
7801     private final boolean checkHoldingPermissionsLocked(
7802             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7803         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7804                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7805         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7806             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7807                     != PERMISSION_GRANTED) {
7808                 return false;
7809             }
7810         }
7811         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7812     }
7813
7814     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7815             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7816         if (pi.applicationInfo.uid == uid) {
7817             return true;
7818         } else if (!pi.exported) {
7819             return false;
7820         }
7821
7822         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7823         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7824         try {
7825             // check if target holds top-level <provider> permissions
7826             if (!readMet && pi.readPermission != null && considerUidPermissions
7827                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7828                 readMet = true;
7829             }
7830             if (!writeMet && pi.writePermission != null && considerUidPermissions
7831                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7832                 writeMet = true;
7833             }
7834
7835             // track if unprotected read/write is allowed; any denied
7836             // <path-permission> below removes this ability
7837             boolean allowDefaultRead = pi.readPermission == null;
7838             boolean allowDefaultWrite = pi.writePermission == null;
7839
7840             // check if target holds any <path-permission> that match uri
7841             final PathPermission[] pps = pi.pathPermissions;
7842             if (pps != null) {
7843                 final String path = grantUri.uri.getPath();
7844                 int i = pps.length;
7845                 while (i > 0 && (!readMet || !writeMet)) {
7846                     i--;
7847                     PathPermission pp = pps[i];
7848                     if (pp.match(path)) {
7849                         if (!readMet) {
7850                             final String pprperm = pp.getReadPermission();
7851                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7852                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7853                                     + ": match=" + pp.match(path)
7854                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7855                             if (pprperm != null) {
7856                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7857                                         == PERMISSION_GRANTED) {
7858                                     readMet = true;
7859                                 } else {
7860                                     allowDefaultRead = false;
7861                                 }
7862                             }
7863                         }
7864                         if (!writeMet) {
7865                             final String ppwperm = pp.getWritePermission();
7866                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7867                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7868                                     + ": match=" + pp.match(path)
7869                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7870                             if (ppwperm != null) {
7871                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7872                                         == PERMISSION_GRANTED) {
7873                                     writeMet = true;
7874                                 } else {
7875                                     allowDefaultWrite = false;
7876                                 }
7877                             }
7878                         }
7879                     }
7880                 }
7881             }
7882
7883             // grant unprotected <provider> read/write, if not blocked by
7884             // <path-permission> above
7885             if (allowDefaultRead) readMet = true;
7886             if (allowDefaultWrite) writeMet = true;
7887
7888         } catch (RemoteException e) {
7889             return false;
7890         }
7891
7892         return readMet && writeMet;
7893     }
7894
7895     public int getAppStartMode(int uid, String packageName) {
7896         synchronized (this) {
7897             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7898         }
7899     }
7900
7901     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7902             boolean allowWhenForeground) {
7903         UidRecord uidRec = mActiveUids.get(uid);
7904         if (!mLenientBackgroundCheck) {
7905             if (!allowWhenForeground || uidRec == null
7906                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7907                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7908                         packageName) != AppOpsManager.MODE_ALLOWED) {
7909                     return ActivityManager.APP_START_MODE_DELAYED;
7910                 }
7911             }
7912
7913         } else if (uidRec == null || uidRec.idle) {
7914             if (callingPid >= 0) {
7915                 ProcessRecord proc;
7916                 synchronized (mPidsSelfLocked) {
7917                     proc = mPidsSelfLocked.get(callingPid);
7918                 }
7919                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7920                     // Whoever is instigating this is in the foreground, so we will allow it
7921                     // to go through.
7922                     return ActivityManager.APP_START_MODE_NORMAL;
7923                 }
7924             }
7925             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7926                     != AppOpsManager.MODE_ALLOWED) {
7927                 return ActivityManager.APP_START_MODE_DELAYED;
7928             }
7929         }
7930         return ActivityManager.APP_START_MODE_NORMAL;
7931     }
7932
7933     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7934         ProviderInfo pi = null;
7935         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7936         if (cpr != null) {
7937             pi = cpr.info;
7938         } else {
7939             try {
7940                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7941                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7942                         userHandle);
7943             } catch (RemoteException ex) {
7944             }
7945         }
7946         return pi;
7947     }
7948
7949     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7950         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7951         if (targetUris != null) {
7952             return targetUris.get(grantUri);
7953         }
7954         return null;
7955     }
7956
7957     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7958             String targetPkg, int targetUid, GrantUri grantUri) {
7959         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7960         if (targetUris == null) {
7961             targetUris = Maps.newArrayMap();
7962             mGrantedUriPermissions.put(targetUid, targetUris);
7963         }
7964
7965         UriPermission perm = targetUris.get(grantUri);
7966         if (perm == null) {
7967             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7968             targetUris.put(grantUri, perm);
7969         }
7970
7971         return perm;
7972     }
7973
7974     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7975             final int modeFlags) {
7976         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7977         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7978                 : UriPermission.STRENGTH_OWNED;
7979
7980         // Root gets to do everything.
7981         if (uid == 0) {
7982             return true;
7983         }
7984
7985         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7986         if (perms == null) return false;
7987
7988         // First look for exact match
7989         final UriPermission exactPerm = perms.get(grantUri);
7990         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7991             return true;
7992         }
7993
7994         // No exact match, look for prefixes
7995         final int N = perms.size();
7996         for (int i = 0; i < N; i++) {
7997             final UriPermission perm = perms.valueAt(i);
7998             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7999                     && perm.getStrength(modeFlags) >= minStrength) {
8000                 return true;
8001             }
8002         }
8003
8004         return false;
8005     }
8006
8007     /**
8008      * @param uri This uri must NOT contain an embedded userId.
8009      * @param userId The userId in which the uri is to be resolved.
8010      */
8011     @Override
8012     public int checkUriPermission(Uri uri, int pid, int uid,
8013             final int modeFlags, int userId, IBinder callerToken) {
8014         enforceNotIsolatedCaller("checkUriPermission");
8015
8016         // Another redirected-binder-call permissions check as in
8017         // {@link checkPermissionWithToken}.
8018         Identity tlsIdentity = sCallerIdentity.get();
8019         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8020             uid = tlsIdentity.uid;
8021             pid = tlsIdentity.pid;
8022         }
8023
8024         // Our own process gets to do everything.
8025         if (pid == MY_PID) {
8026             return PackageManager.PERMISSION_GRANTED;
8027         }
8028         synchronized (this) {
8029             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8030                     ? PackageManager.PERMISSION_GRANTED
8031                     : PackageManager.PERMISSION_DENIED;
8032         }
8033     }
8034
8035     /**
8036      * Check if the targetPkg can be granted permission to access uri by
8037      * the callingUid using the given modeFlags.  Throws a security exception
8038      * if callingUid is not allowed to do this.  Returns the uid of the target
8039      * if the URI permission grant should be performed; returns -1 if it is not
8040      * needed (for example targetPkg already has permission to access the URI).
8041      * If you already know the uid of the target, you can supply it in
8042      * lastTargetUid else set that to -1.
8043      */
8044     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8045             final int modeFlags, int lastTargetUid) {
8046         if (!Intent.isAccessUriMode(modeFlags)) {
8047             return -1;
8048         }
8049
8050         if (targetPkg != null) {
8051             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8052                     "Checking grant " + targetPkg + " permission to " + grantUri);
8053         }
8054
8055         final IPackageManager pm = AppGlobals.getPackageManager();
8056
8057         // If this is not a content: uri, we can't do anything with it.
8058         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8059             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8060                     "Can't grant URI permission for non-content URI: " + grantUri);
8061             return -1;
8062         }
8063
8064         final String authority = grantUri.uri.getAuthority();
8065         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8066                 MATCH_DEBUG_TRIAGED_MISSING);
8067         if (pi == null) {
8068             Slog.w(TAG, "No content provider found for permission check: " +
8069                     grantUri.uri.toSafeString());
8070             return -1;
8071         }
8072
8073         int targetUid = lastTargetUid;
8074         if (targetUid < 0 && targetPkg != null) {
8075             try {
8076                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8077                         UserHandle.getUserId(callingUid));
8078                 if (targetUid < 0) {
8079                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8080                             "Can't grant URI permission no uid for: " + targetPkg);
8081                     return -1;
8082                 }
8083             } catch (RemoteException ex) {
8084                 return -1;
8085             }
8086         }
8087
8088         if (targetUid >= 0) {
8089             // First...  does the target actually need this permission?
8090             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8091                 // No need to grant the target this permission.
8092                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8093                         "Target " + targetPkg + " already has full permission to " + grantUri);
8094                 return -1;
8095             }
8096         } else {
8097             // First...  there is no target package, so can anyone access it?
8098             boolean allowed = pi.exported;
8099             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8100                 if (pi.readPermission != null) {
8101                     allowed = false;
8102                 }
8103             }
8104             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8105                 if (pi.writePermission != null) {
8106                     allowed = false;
8107                 }
8108             }
8109             if (allowed) {
8110                 return -1;
8111             }
8112         }
8113
8114         /* There is a special cross user grant if:
8115          * - The target is on another user.
8116          * - Apps on the current user can access the uri without any uid permissions.
8117          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8118          * grant uri permissions.
8119          */
8120         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8121                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8122                 modeFlags, false /*without considering the uid permissions*/);
8123
8124         // Second...  is the provider allowing granting of URI permissions?
8125         if (!specialCrossUserGrant) {
8126             if (!pi.grantUriPermissions) {
8127                 throw new SecurityException("Provider " + pi.packageName
8128                         + "/" + pi.name
8129                         + " does not allow granting of Uri permissions (uri "
8130                         + grantUri + ")");
8131             }
8132             if (pi.uriPermissionPatterns != null) {
8133                 final int N = pi.uriPermissionPatterns.length;
8134                 boolean allowed = false;
8135                 for (int i=0; i<N; i++) {
8136                     if (pi.uriPermissionPatterns[i] != null
8137                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8138                         allowed = true;
8139                         break;
8140                     }
8141                 }
8142                 if (!allowed) {
8143                     throw new SecurityException("Provider " + pi.packageName
8144                             + "/" + pi.name
8145                             + " does not allow granting of permission to path of Uri "
8146                             + grantUri);
8147                 }
8148             }
8149         }
8150
8151         // Third...  does the caller itself have permission to access
8152         // this uri?
8153         final int callingAppId = UserHandle.getAppId(callingUid);
8154         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8155             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8156                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8157             return -1;
8158         } else {
8159             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8160                 // Require they hold a strong enough Uri permission
8161                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8162                     throw new SecurityException("Uid " + callingUid
8163                             + " does not have permission to uri " + grantUri);
8164                 }
8165             }
8166         }
8167         return targetUid;
8168     }
8169
8170     /**
8171      * @param uri This uri must NOT contain an embedded userId.
8172      * @param userId The userId in which the uri is to be resolved.
8173      */
8174     @Override
8175     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8176             final int modeFlags, int userId) {
8177         enforceNotIsolatedCaller("checkGrantUriPermission");
8178         synchronized(this) {
8179             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8180                     new GrantUri(userId, uri, false), modeFlags, -1);
8181         }
8182     }
8183
8184     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8185             final int modeFlags, UriPermissionOwner owner) {
8186         if (!Intent.isAccessUriMode(modeFlags)) {
8187             return;
8188         }
8189
8190         // So here we are: the caller has the assumed permission
8191         // to the uri, and the target doesn't.  Let's now give this to
8192         // the target.
8193
8194         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8195                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8196
8197         final String authority = grantUri.uri.getAuthority();
8198         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8199                 MATCH_DEBUG_TRIAGED_MISSING);
8200         if (pi == null) {
8201             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8202             return;
8203         }
8204
8205         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8206             grantUri.prefix = true;
8207         }
8208         final UriPermission perm = findOrCreateUriPermissionLocked(
8209                 pi.packageName, targetPkg, targetUid, grantUri);
8210         perm.grantModes(modeFlags, owner);
8211     }
8212
8213     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8214             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8215         if (targetPkg == null) {
8216             throw new NullPointerException("targetPkg");
8217         }
8218         int targetUid;
8219         final IPackageManager pm = AppGlobals.getPackageManager();
8220         try {
8221             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8222         } catch (RemoteException ex) {
8223             return;
8224         }
8225
8226         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8227                 targetUid);
8228         if (targetUid < 0) {
8229             return;
8230         }
8231
8232         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8233                 owner);
8234     }
8235
8236     static class NeededUriGrants extends ArrayList<GrantUri> {
8237         final String targetPkg;
8238         final int targetUid;
8239         final int flags;
8240
8241         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8242             this.targetPkg = targetPkg;
8243             this.targetUid = targetUid;
8244             this.flags = flags;
8245         }
8246     }
8247
8248     /**
8249      * Like checkGrantUriPermissionLocked, but takes an Intent.
8250      */
8251     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8252             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8253         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8254                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8255                 + " clip=" + (intent != null ? intent.getClipData() : null)
8256                 + " from " + intent + "; flags=0x"
8257                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8258
8259         if (targetPkg == null) {
8260             throw new NullPointerException("targetPkg");
8261         }
8262
8263         if (intent == null) {
8264             return null;
8265         }
8266         Uri data = intent.getData();
8267         ClipData clip = intent.getClipData();
8268         if (data == null && clip == null) {
8269             return null;
8270         }
8271         // Default userId for uris in the intent (if they don't specify it themselves)
8272         int contentUserHint = intent.getContentUserHint();
8273         if (contentUserHint == UserHandle.USER_CURRENT) {
8274             contentUserHint = UserHandle.getUserId(callingUid);
8275         }
8276         final IPackageManager pm = AppGlobals.getPackageManager();
8277         int targetUid;
8278         if (needed != null) {
8279             targetUid = needed.targetUid;
8280         } else {
8281             try {
8282                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8283                         targetUserId);
8284             } catch (RemoteException ex) {
8285                 return null;
8286             }
8287             if (targetUid < 0) {
8288                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8289                         "Can't grant URI permission no uid for: " + targetPkg
8290                         + " on user " + targetUserId);
8291                 return null;
8292             }
8293         }
8294         if (data != null) {
8295             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8296             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8297                     targetUid);
8298             if (targetUid > 0) {
8299                 if (needed == null) {
8300                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8301                 }
8302                 needed.add(grantUri);
8303             }
8304         }
8305         if (clip != null) {
8306             for (int i=0; i<clip.getItemCount(); i++) {
8307                 Uri uri = clip.getItemAt(i).getUri();
8308                 if (uri != null) {
8309                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8310                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8311                             targetUid);
8312                     if (targetUid > 0) {
8313                         if (needed == null) {
8314                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8315                         }
8316                         needed.add(grantUri);
8317                     }
8318                 } else {
8319                     Intent clipIntent = clip.getItemAt(i).getIntent();
8320                     if (clipIntent != null) {
8321                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8322                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8323                         if (newNeeded != null) {
8324                             needed = newNeeded;
8325                         }
8326                     }
8327                 }
8328             }
8329         }
8330
8331         return needed;
8332     }
8333
8334     /**
8335      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8336      */
8337     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8338             UriPermissionOwner owner) {
8339         if (needed != null) {
8340             for (int i=0; i<needed.size(); i++) {
8341                 GrantUri grantUri = needed.get(i);
8342                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8343                         grantUri, needed.flags, owner);
8344             }
8345         }
8346     }
8347
8348     void grantUriPermissionFromIntentLocked(int callingUid,
8349             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8350         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8351                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8352         if (needed == null) {
8353             return;
8354         }
8355
8356         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8357     }
8358
8359     /**
8360      * @param uri This uri must NOT contain an embedded userId.
8361      * @param userId The userId in which the uri is to be resolved.
8362      */
8363     @Override
8364     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8365             final int modeFlags, int userId) {
8366         enforceNotIsolatedCaller("grantUriPermission");
8367         GrantUri grantUri = new GrantUri(userId, uri, false);
8368         synchronized(this) {
8369             final ProcessRecord r = getRecordForAppLocked(caller);
8370             if (r == null) {
8371                 throw new SecurityException("Unable to find app for caller "
8372                         + caller
8373                         + " when granting permission to uri " + grantUri);
8374             }
8375             if (targetPkg == null) {
8376                 throw new IllegalArgumentException("null target");
8377             }
8378             if (grantUri == null) {
8379                 throw new IllegalArgumentException("null uri");
8380             }
8381
8382             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8383                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8384                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8385                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8386
8387             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8388                     UserHandle.getUserId(r.uid));
8389         }
8390     }
8391
8392     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8393         if (perm.modeFlags == 0) {
8394             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8395                     perm.targetUid);
8396             if (perms != null) {
8397                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8398                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8399
8400                 perms.remove(perm.uri);
8401                 if (perms.isEmpty()) {
8402                     mGrantedUriPermissions.remove(perm.targetUid);
8403                 }
8404             }
8405         }
8406     }
8407
8408     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8409         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8410                 "Revoking all granted permissions to " + grantUri);
8411
8412         final IPackageManager pm = AppGlobals.getPackageManager();
8413         final String authority = grantUri.uri.getAuthority();
8414         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8415                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8416         if (pi == null) {
8417             Slog.w(TAG, "No content provider found for permission revoke: "
8418                     + grantUri.toSafeString());
8419             return;
8420         }
8421
8422         // Does the caller have this permission on the URI?
8423         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8424             // If they don't have direct access to the URI, then revoke any
8425             // ownerless URI permissions that have been granted to them.
8426             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8427             if (perms != null) {
8428                 boolean persistChanged = false;
8429                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8430                     final UriPermission perm = it.next();
8431                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8432                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8433                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8434                                 "Revoking non-owned " + perm.targetUid
8435                                 + " permission to " + perm.uri);
8436                         persistChanged |= perm.revokeModes(
8437                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8438                         if (perm.modeFlags == 0) {
8439                             it.remove();
8440                         }
8441                     }
8442                 }
8443                 if (perms.isEmpty()) {
8444                     mGrantedUriPermissions.remove(callingUid);
8445                 }
8446                 if (persistChanged) {
8447                     schedulePersistUriGrants();
8448                 }
8449             }
8450             return;
8451         }
8452
8453         boolean persistChanged = false;
8454
8455         // Go through all of the permissions and remove any that match.
8456         int N = mGrantedUriPermissions.size();
8457         for (int i = 0; i < N; i++) {
8458             final int targetUid = mGrantedUriPermissions.keyAt(i);
8459             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8460
8461             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8462                 final UriPermission perm = it.next();
8463                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8464                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8465                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8466                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8467                     persistChanged |= perm.revokeModes(
8468                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8469                     if (perm.modeFlags == 0) {
8470                         it.remove();
8471                     }
8472                 }
8473             }
8474
8475             if (perms.isEmpty()) {
8476                 mGrantedUriPermissions.remove(targetUid);
8477                 N--;
8478                 i--;
8479             }
8480         }
8481
8482         if (persistChanged) {
8483             schedulePersistUriGrants();
8484         }
8485     }
8486
8487     /**
8488      * @param uri This uri must NOT contain an embedded userId.
8489      * @param userId The userId in which the uri is to be resolved.
8490      */
8491     @Override
8492     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8493             int userId) {
8494         enforceNotIsolatedCaller("revokeUriPermission");
8495         synchronized(this) {
8496             final ProcessRecord r = getRecordForAppLocked(caller);
8497             if (r == null) {
8498                 throw new SecurityException("Unable to find app for caller "
8499                         + caller
8500                         + " when revoking permission to uri " + uri);
8501             }
8502             if (uri == null) {
8503                 Slog.w(TAG, "revokeUriPermission: null uri");
8504                 return;
8505             }
8506
8507             if (!Intent.isAccessUriMode(modeFlags)) {
8508                 return;
8509             }
8510
8511             final String authority = uri.getAuthority();
8512             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8513                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8514             if (pi == null) {
8515                 Slog.w(TAG, "No content provider found for permission revoke: "
8516                         + uri.toSafeString());
8517                 return;
8518             }
8519
8520             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8521         }
8522     }
8523
8524     /**
8525      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8526      * given package.
8527      *
8528      * @param packageName Package name to match, or {@code null} to apply to all
8529      *            packages.
8530      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8531      *            to all users.
8532      * @param persistable If persistable grants should be removed.
8533      */
8534     private void removeUriPermissionsForPackageLocked(
8535             String packageName, int userHandle, boolean persistable) {
8536         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8537             throw new IllegalArgumentException("Must narrow by either package or user");
8538         }
8539
8540         boolean persistChanged = false;
8541
8542         int N = mGrantedUriPermissions.size();
8543         for (int i = 0; i < N; i++) {
8544             final int targetUid = mGrantedUriPermissions.keyAt(i);
8545             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8546
8547             // Only inspect grants matching user
8548             if (userHandle == UserHandle.USER_ALL
8549                     || userHandle == UserHandle.getUserId(targetUid)) {
8550                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8551                     final UriPermission perm = it.next();
8552
8553                     // Only inspect grants matching package
8554                     if (packageName == null || perm.sourcePkg.equals(packageName)
8555                             || perm.targetPkg.equals(packageName)) {
8556                         // Hacky solution as part of fixing a security bug; ignore
8557                         // grants associated with DownloadManager so we don't have
8558                         // to immediately launch it to regrant the permissions
8559                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8560                                 && !persistable) continue;
8561
8562                         persistChanged |= perm.revokeModes(persistable
8563                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8564
8565                         // Only remove when no modes remain; any persisted grants
8566                         // will keep this alive.
8567                         if (perm.modeFlags == 0) {
8568                             it.remove();
8569                         }
8570                     }
8571                 }
8572
8573                 if (perms.isEmpty()) {
8574                     mGrantedUriPermissions.remove(targetUid);
8575                     N--;
8576                     i--;
8577                 }
8578             }
8579         }
8580
8581         if (persistChanged) {
8582             schedulePersistUriGrants();
8583         }
8584     }
8585
8586     @Override
8587     public IBinder newUriPermissionOwner(String name) {
8588         enforceNotIsolatedCaller("newUriPermissionOwner");
8589         synchronized(this) {
8590             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8591             return owner.getExternalTokenLocked();
8592         }
8593     }
8594
8595     @Override
8596     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8597         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8598         synchronized(this) {
8599             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8600             if (r == null) {
8601                 throw new IllegalArgumentException("Activity does not exist; token="
8602                         + activityToken);
8603             }
8604             return r.getUriPermissionsLocked().getExternalTokenLocked();
8605         }
8606     }
8607     /**
8608      * @param uri This uri must NOT contain an embedded userId.
8609      * @param sourceUserId The userId in which the uri is to be resolved.
8610      * @param targetUserId The userId of the app that receives the grant.
8611      */
8612     @Override
8613     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8614             final int modeFlags, int sourceUserId, int targetUserId) {
8615         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8616                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8617                 "grantUriPermissionFromOwner", null);
8618         synchronized(this) {
8619             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8620             if (owner == null) {
8621                 throw new IllegalArgumentException("Unknown owner: " + token);
8622             }
8623             if (fromUid != Binder.getCallingUid()) {
8624                 if (Binder.getCallingUid() != Process.myUid()) {
8625                     // Only system code can grant URI permissions on behalf
8626                     // of other users.
8627                     throw new SecurityException("nice try");
8628                 }
8629             }
8630             if (targetPkg == null) {
8631                 throw new IllegalArgumentException("null target");
8632             }
8633             if (uri == null) {
8634                 throw new IllegalArgumentException("null uri");
8635             }
8636
8637             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8638                     modeFlags, owner, targetUserId);
8639         }
8640     }
8641
8642     /**
8643      * @param uri This uri must NOT contain an embedded userId.
8644      * @param userId The userId in which the uri is to be resolved.
8645      */
8646     @Override
8647     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8648         synchronized(this) {
8649             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8650             if (owner == null) {
8651                 throw new IllegalArgumentException("Unknown owner: " + token);
8652             }
8653
8654             if (uri == null) {
8655                 owner.removeUriPermissionsLocked(mode);
8656             } else {
8657                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8658                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8659             }
8660         }
8661     }
8662
8663     private void schedulePersistUriGrants() {
8664         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8665             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8666                     10 * DateUtils.SECOND_IN_MILLIS);
8667         }
8668     }
8669
8670     private void writeGrantedUriPermissions() {
8671         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8672
8673         // Snapshot permissions so we can persist without lock
8674         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8675         synchronized (this) {
8676             final int size = mGrantedUriPermissions.size();
8677             for (int i = 0; i < size; i++) {
8678                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8679                 for (UriPermission perm : perms.values()) {
8680                     if (perm.persistedModeFlags != 0) {
8681                         persist.add(perm.snapshot());
8682                     }
8683                 }
8684             }
8685         }
8686
8687         FileOutputStream fos = null;
8688         try {
8689             fos = mGrantFile.startWrite();
8690
8691             XmlSerializer out = new FastXmlSerializer();
8692             out.setOutput(fos, StandardCharsets.UTF_8.name());
8693             out.startDocument(null, true);
8694             out.startTag(null, TAG_URI_GRANTS);
8695             for (UriPermission.Snapshot perm : persist) {
8696                 out.startTag(null, TAG_URI_GRANT);
8697                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8698                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8699                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8700                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8701                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8702                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8703                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8704                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8705                 out.endTag(null, TAG_URI_GRANT);
8706             }
8707             out.endTag(null, TAG_URI_GRANTS);
8708             out.endDocument();
8709
8710             mGrantFile.finishWrite(fos);
8711         } catch (IOException e) {
8712             if (fos != null) {
8713                 mGrantFile.failWrite(fos);
8714             }
8715         }
8716     }
8717
8718     private void readGrantedUriPermissionsLocked() {
8719         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8720
8721         final long now = System.currentTimeMillis();
8722
8723         FileInputStream fis = null;
8724         try {
8725             fis = mGrantFile.openRead();
8726             final XmlPullParser in = Xml.newPullParser();
8727             in.setInput(fis, StandardCharsets.UTF_8.name());
8728
8729             int type;
8730             while ((type = in.next()) != END_DOCUMENT) {
8731                 final String tag = in.getName();
8732                 if (type == START_TAG) {
8733                     if (TAG_URI_GRANT.equals(tag)) {
8734                         final int sourceUserId;
8735                         final int targetUserId;
8736                         final int userHandle = readIntAttribute(in,
8737                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8738                         if (userHandle != UserHandle.USER_NULL) {
8739                             // For backwards compatibility.
8740                             sourceUserId = userHandle;
8741                             targetUserId = userHandle;
8742                         } else {
8743                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8744                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8745                         }
8746                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8747                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8748                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8749                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8750                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8751                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8752
8753                         // Sanity check that provider still belongs to source package
8754                         // Both direct boot aware and unaware packages are fine as we
8755                         // will do filtering at query time to avoid multiple parsing.
8756                         final ProviderInfo pi = getProviderInfoLocked(
8757                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8758                                         | MATCH_DIRECT_BOOT_UNAWARE);
8759                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8760                             int targetUid = -1;
8761                             try {
8762                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8763                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8764                             } catch (RemoteException e) {
8765                             }
8766                             if (targetUid != -1) {
8767                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8768                                         sourcePkg, targetPkg, targetUid,
8769                                         new GrantUri(sourceUserId, uri, prefix));
8770                                 perm.initPersistedModes(modeFlags, createdTime);
8771                             }
8772                         } else {
8773                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8774                                     + " but instead found " + pi);
8775                         }
8776                     }
8777                 }
8778             }
8779         } catch (FileNotFoundException e) {
8780             // Missing grants is okay
8781         } catch (IOException e) {
8782             Slog.wtf(TAG, "Failed reading Uri grants", e);
8783         } catch (XmlPullParserException e) {
8784             Slog.wtf(TAG, "Failed reading Uri grants", e);
8785         } finally {
8786             IoUtils.closeQuietly(fis);
8787         }
8788     }
8789
8790     /**
8791      * @param uri This uri must NOT contain an embedded userId.
8792      * @param userId The userId in which the uri is to be resolved.
8793      */
8794     @Override
8795     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8796         enforceNotIsolatedCaller("takePersistableUriPermission");
8797
8798         Preconditions.checkFlagsArgument(modeFlags,
8799                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8800
8801         synchronized (this) {
8802             final int callingUid = Binder.getCallingUid();
8803             boolean persistChanged = false;
8804             GrantUri grantUri = new GrantUri(userId, uri, false);
8805
8806             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8807                     new GrantUri(userId, uri, false));
8808             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8809                     new GrantUri(userId, uri, true));
8810
8811             final boolean exactValid = (exactPerm != null)
8812                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8813             final boolean prefixValid = (prefixPerm != null)
8814                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8815
8816             if (!(exactValid || prefixValid)) {
8817                 throw new SecurityException("No persistable permission grants found for UID "
8818                         + callingUid + " and Uri " + grantUri.toSafeString());
8819             }
8820
8821             if (exactValid) {
8822                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8823             }
8824             if (prefixValid) {
8825                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8826             }
8827
8828             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8829
8830             if (persistChanged) {
8831                 schedulePersistUriGrants();
8832             }
8833         }
8834     }
8835
8836     /**
8837      * @param uri This uri must NOT contain an embedded userId.
8838      * @param userId The userId in which the uri is to be resolved.
8839      */
8840     @Override
8841     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8842         enforceNotIsolatedCaller("releasePersistableUriPermission");
8843
8844         Preconditions.checkFlagsArgument(modeFlags,
8845                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8846
8847         synchronized (this) {
8848             final int callingUid = Binder.getCallingUid();
8849             boolean persistChanged = false;
8850
8851             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8852                     new GrantUri(userId, uri, false));
8853             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8854                     new GrantUri(userId, uri, true));
8855             if (exactPerm == null && prefixPerm == null) {
8856                 throw new SecurityException("No permission grants found for UID " + callingUid
8857                         + " and Uri " + uri.toSafeString());
8858             }
8859
8860             if (exactPerm != null) {
8861                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8862                 removeUriPermissionIfNeededLocked(exactPerm);
8863             }
8864             if (prefixPerm != null) {
8865                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8866                 removeUriPermissionIfNeededLocked(prefixPerm);
8867             }
8868
8869             if (persistChanged) {
8870                 schedulePersistUriGrants();
8871             }
8872         }
8873     }
8874
8875     /**
8876      * Prune any older {@link UriPermission} for the given UID until outstanding
8877      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8878      *
8879      * @return if any mutations occured that require persisting.
8880      */
8881     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8882         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8883         if (perms == null) return false;
8884         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8885
8886         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8887         for (UriPermission perm : perms.values()) {
8888             if (perm.persistedModeFlags != 0) {
8889                 persisted.add(perm);
8890             }
8891         }
8892
8893         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8894         if (trimCount <= 0) return false;
8895
8896         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8897         for (int i = 0; i < trimCount; i++) {
8898             final UriPermission perm = persisted.get(i);
8899
8900             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8901                     "Trimming grant created at " + perm.persistedCreateTime);
8902
8903             perm.releasePersistableModes(~0);
8904             removeUriPermissionIfNeededLocked(perm);
8905         }
8906
8907         return true;
8908     }
8909
8910     @Override
8911     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8912             String packageName, boolean incoming) {
8913         enforceNotIsolatedCaller("getPersistedUriPermissions");
8914         Preconditions.checkNotNull(packageName, "packageName");
8915
8916         final int callingUid = Binder.getCallingUid();
8917         final int callingUserId = UserHandle.getUserId(callingUid);
8918         final IPackageManager pm = AppGlobals.getPackageManager();
8919         try {
8920             final int packageUid = pm.getPackageUid(packageName,
8921                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8922             if (packageUid != callingUid) {
8923                 throw new SecurityException(
8924                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8925             }
8926         } catch (RemoteException e) {
8927             throw new SecurityException("Failed to verify package name ownership");
8928         }
8929
8930         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8931         synchronized (this) {
8932             if (incoming) {
8933                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8934                         callingUid);
8935                 if (perms == null) {
8936                     Slog.w(TAG, "No permission grants found for " + packageName);
8937                 } else {
8938                     for (UriPermission perm : perms.values()) {
8939                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8940                             result.add(perm.buildPersistedPublicApiObject());
8941                         }
8942                     }
8943                 }
8944             } else {
8945                 final int size = mGrantedUriPermissions.size();
8946                 for (int i = 0; i < size; i++) {
8947                     final ArrayMap<GrantUri, UriPermission> perms =
8948                             mGrantedUriPermissions.valueAt(i);
8949                     for (UriPermission perm : perms.values()) {
8950                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8951                             result.add(perm.buildPersistedPublicApiObject());
8952                         }
8953                     }
8954                 }
8955             }
8956         }
8957         return new ParceledListSlice<android.content.UriPermission>(result);
8958     }
8959
8960     @Override
8961     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8962             String packageName, int userId) {
8963         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8964                 "getGrantedUriPermissions");
8965
8966         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8967         synchronized (this) {
8968             final int size = mGrantedUriPermissions.size();
8969             for (int i = 0; i < size; i++) {
8970                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8971                 for (UriPermission perm : perms.values()) {
8972                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8973                             && perm.persistedModeFlags != 0) {
8974                         result.add(perm.buildPersistedPublicApiObject());
8975                     }
8976                 }
8977             }
8978         }
8979         return new ParceledListSlice<android.content.UriPermission>(result);
8980     }
8981
8982     @Override
8983     public void clearGrantedUriPermissions(String packageName, int userId) {
8984         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8985                 "clearGrantedUriPermissions");
8986         removeUriPermissionsForPackageLocked(packageName, userId, true);
8987     }
8988
8989     @Override
8990     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8991         synchronized (this) {
8992             ProcessRecord app =
8993                 who != null ? getRecordForAppLocked(who) : null;
8994             if (app == null) return;
8995
8996             Message msg = Message.obtain();
8997             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8998             msg.obj = app;
8999             msg.arg1 = waiting ? 1 : 0;
9000             mUiHandler.sendMessage(msg);
9001         }
9002     }
9003
9004     @Override
9005     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9006         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9007         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9008         outInfo.availMem = Process.getFreeMemory();
9009         outInfo.totalMem = Process.getTotalMemory();
9010         outInfo.threshold = homeAppMem;
9011         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9012         outInfo.hiddenAppThreshold = cachedAppMem;
9013         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9014                 ProcessList.SERVICE_ADJ);
9015         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9016                 ProcessList.VISIBLE_APP_ADJ);
9017         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9018                 ProcessList.FOREGROUND_APP_ADJ);
9019     }
9020
9021     // =========================================================
9022     // TASK MANAGEMENT
9023     // =========================================================
9024
9025     @Override
9026     public List<IAppTask> getAppTasks(String callingPackage) {
9027         int callingUid = Binder.getCallingUid();
9028         long ident = Binder.clearCallingIdentity();
9029
9030         synchronized(this) {
9031             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9032             try {
9033                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9034
9035                 final int N = mRecentTasks.size();
9036                 for (int i = 0; i < N; i++) {
9037                     TaskRecord tr = mRecentTasks.get(i);
9038                     // Skip tasks that do not match the caller.  We don't need to verify
9039                     // callingPackage, because we are also limiting to callingUid and know
9040                     // that will limit to the correct security sandbox.
9041                     if (tr.effectiveUid != callingUid) {
9042                         continue;
9043                     }
9044                     Intent intent = tr.getBaseIntent();
9045                     if (intent == null ||
9046                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9047                         continue;
9048                     }
9049                     ActivityManager.RecentTaskInfo taskInfo =
9050                             createRecentTaskInfoFromTaskRecord(tr);
9051                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9052                     list.add(taskImpl);
9053                 }
9054             } finally {
9055                 Binder.restoreCallingIdentity(ident);
9056             }
9057             return list;
9058         }
9059     }
9060
9061     @Override
9062     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9063         final int callingUid = Binder.getCallingUid();
9064         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9065
9066         synchronized(this) {
9067             if (DEBUG_ALL) Slog.v(
9068                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9069
9070             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9071                     callingUid);
9072
9073             // TODO: Improve with MRU list from all ActivityStacks.
9074             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9075         }
9076
9077         return list;
9078     }
9079
9080     /**
9081      * Creates a new RecentTaskInfo from a TaskRecord.
9082      */
9083     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9084         // Update the task description to reflect any changes in the task stack
9085         tr.updateTaskDescription();
9086
9087         // Compose the recent task info
9088         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9089         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9090         rti.persistentId = tr.taskId;
9091         rti.baseIntent = new Intent(tr.getBaseIntent());
9092         rti.origActivity = tr.origActivity;
9093         rti.realActivity = tr.realActivity;
9094         rti.description = tr.lastDescription;
9095         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9096         rti.userId = tr.userId;
9097         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9098         rti.firstActiveTime = tr.firstActiveTime;
9099         rti.lastActiveTime = tr.lastActiveTime;
9100         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9101         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9102         rti.numActivities = 0;
9103         if (tr.mBounds != null) {
9104             rti.bounds = new Rect(tr.mBounds);
9105         }
9106         rti.isDockable = tr.canGoInDockedStack();
9107         rti.resizeMode = tr.mResizeMode;
9108
9109         ActivityRecord base = null;
9110         ActivityRecord top = null;
9111         ActivityRecord tmp;
9112
9113         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9114             tmp = tr.mActivities.get(i);
9115             if (tmp.finishing) {
9116                 continue;
9117             }
9118             base = tmp;
9119             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9120                 top = base;
9121             }
9122             rti.numActivities++;
9123         }
9124
9125         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9126         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9127
9128         return rti;
9129     }
9130
9131     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9132         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9133                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9134         if (!allowed) {
9135             if (checkPermission(android.Manifest.permission.GET_TASKS,
9136                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9137                 // Temporary compatibility: some existing apps on the system image may
9138                 // still be requesting the old permission and not switched to the new
9139                 // one; if so, we'll still allow them full access.  This means we need
9140                 // to see if they are holding the old permission and are a system app.
9141                 try {
9142                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9143                         allowed = true;
9144                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9145                                 + " is using old GET_TASKS but privileged; allowing");
9146                     }
9147                 } catch (RemoteException e) {
9148                 }
9149             }
9150         }
9151         if (!allowed) {
9152             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9153                     + " does not hold REAL_GET_TASKS; limiting output");
9154         }
9155         return allowed;
9156     }
9157
9158     @Override
9159     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9160             int userId) {
9161         final int callingUid = Binder.getCallingUid();
9162         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9163                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9164
9165         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9166         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9167         synchronized (this) {
9168             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9169                     callingUid);
9170             final boolean detailed = checkCallingPermission(
9171                     android.Manifest.permission.GET_DETAILED_TASKS)
9172                     == PackageManager.PERMISSION_GRANTED;
9173
9174             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9175                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9176                 return ParceledListSlice.emptyList();
9177             }
9178             mRecentTasks.loadUserRecentsLocked(userId);
9179
9180             final int recentsCount = mRecentTasks.size();
9181             ArrayList<ActivityManager.RecentTaskInfo> res =
9182                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9183
9184             final Set<Integer> includedUsers;
9185             if (includeProfiles) {
9186                 includedUsers = mUserController.getProfileIds(userId);
9187             } else {
9188                 includedUsers = new HashSet<>();
9189             }
9190             includedUsers.add(Integer.valueOf(userId));
9191
9192             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9193                 TaskRecord tr = mRecentTasks.get(i);
9194                 // Only add calling user or related users recent tasks
9195                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9196                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9197                     continue;
9198                 }
9199
9200                 if (tr.realActivitySuspended) {
9201                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9202                     continue;
9203                 }
9204
9205                 // Return the entry if desired by the caller.  We always return
9206                 // the first entry, because callers always expect this to be the
9207                 // foreground app.  We may filter others if the caller has
9208                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9209                 // we should exclude the entry.
9210
9211                 if (i == 0
9212                         || withExcluded
9213                         || (tr.intent == null)
9214                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9215                                 == 0)) {
9216                     if (!allowed) {
9217                         // If the caller doesn't have the GET_TASKS permission, then only
9218                         // allow them to see a small subset of tasks -- their own and home.
9219                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9220                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9221                             continue;
9222                         }
9223                     }
9224                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9225                         if (tr.stack != null && tr.stack.isHomeStack()) {
9226                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9227                                     "Skipping, home stack task: " + tr);
9228                             continue;
9229                         }
9230                     }
9231                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9232                         final ActivityStack stack = tr.stack;
9233                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9234                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9235                                     "Skipping, top task in docked stack: " + tr);
9236                             continue;
9237                         }
9238                     }
9239                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9240                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9241                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9242                                     "Skipping, pinned stack task: " + tr);
9243                             continue;
9244                         }
9245                     }
9246                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9247                         // Don't include auto remove tasks that are finished or finishing.
9248                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9249                                 "Skipping, auto-remove without activity: " + tr);
9250                         continue;
9251                     }
9252                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9253                             && !tr.isAvailable) {
9254                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9255                                 "Skipping, unavail real act: " + tr);
9256                         continue;
9257                     }
9258
9259                     if (!tr.mUserSetupComplete) {
9260                         // Don't include task launched while user is not done setting-up.
9261                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9262                                 "Skipping, user setup not complete: " + tr);
9263                         continue;
9264                     }
9265
9266                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9267                     if (!detailed) {
9268                         rti.baseIntent.replaceExtras((Bundle)null);
9269                     }
9270
9271                     res.add(rti);
9272                     maxNum--;
9273                 }
9274             }
9275             return new ParceledListSlice<>(res);
9276         }
9277     }
9278
9279     @Override
9280     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9281         synchronized (this) {
9282             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9283                     "getTaskThumbnail()");
9284             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9285                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9286             if (tr != null) {
9287                 return tr.getTaskThumbnailLocked();
9288             }
9289         }
9290         return null;
9291     }
9292
9293     @Override
9294     public int addAppTask(IBinder activityToken, Intent intent,
9295             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9296         final int callingUid = Binder.getCallingUid();
9297         final long callingIdent = Binder.clearCallingIdentity();
9298
9299         try {
9300             synchronized (this) {
9301                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9302                 if (r == null) {
9303                     throw new IllegalArgumentException("Activity does not exist; token="
9304                             + activityToken);
9305                 }
9306                 ComponentName comp = intent.getComponent();
9307                 if (comp == null) {
9308                     throw new IllegalArgumentException("Intent " + intent
9309                             + " must specify explicit component");
9310                 }
9311                 if (thumbnail.getWidth() != mThumbnailWidth
9312                         || thumbnail.getHeight() != mThumbnailHeight) {
9313                     throw new IllegalArgumentException("Bad thumbnail size: got "
9314                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9315                             + mThumbnailWidth + "x" + mThumbnailHeight);
9316                 }
9317                 if (intent.getSelector() != null) {
9318                     intent.setSelector(null);
9319                 }
9320                 if (intent.getSourceBounds() != null) {
9321                     intent.setSourceBounds(null);
9322                 }
9323                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9324                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9325                         // The caller has added this as an auto-remove task...  that makes no
9326                         // sense, so turn off auto-remove.
9327                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9328                     }
9329                 }
9330                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9331                     mLastAddedTaskActivity = null;
9332                 }
9333                 ActivityInfo ainfo = mLastAddedTaskActivity;
9334                 if (ainfo == null) {
9335                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9336                             comp, 0, UserHandle.getUserId(callingUid));
9337                     if (ainfo.applicationInfo.uid != callingUid) {
9338                         throw new SecurityException(
9339                                 "Can't add task for another application: target uid="
9340                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9341                     }
9342                 }
9343
9344                 // Use the full screen as the context for the task thumbnail
9345                 final Point displaySize = new Point();
9346                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9347                 r.task.stack.getDisplaySize(displaySize);
9348                 thumbnailInfo.taskWidth = displaySize.x;
9349                 thumbnailInfo.taskHeight = displaySize.y;
9350                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9351
9352                 TaskRecord task = new TaskRecord(this,
9353                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9354                         ainfo, intent, description, thumbnailInfo);
9355
9356                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9357                 if (trimIdx >= 0) {
9358                     // If this would have caused a trim, then we'll abort because that
9359                     // means it would be added at the end of the list but then just removed.
9360                     return INVALID_TASK_ID;
9361                 }
9362
9363                 final int N = mRecentTasks.size();
9364                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9365                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9366                     tr.removedFromRecents();
9367                 }
9368
9369                 task.inRecents = true;
9370                 mRecentTasks.add(task);
9371                 r.task.stack.addTask(task, false, "addAppTask");
9372
9373                 task.setLastThumbnailLocked(thumbnail);
9374                 task.freeLastThumbnail();
9375
9376                 return task.taskId;
9377             }
9378         } finally {
9379             Binder.restoreCallingIdentity(callingIdent);
9380         }
9381     }
9382
9383     @Override
9384     public Point getAppTaskThumbnailSize() {
9385         synchronized (this) {
9386             return new Point(mThumbnailWidth,  mThumbnailHeight);
9387         }
9388     }
9389
9390     @Override
9391     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9392         synchronized (this) {
9393             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9394             if (r != null) {
9395                 r.setTaskDescription(td);
9396                 r.task.updateTaskDescription();
9397             }
9398         }
9399     }
9400
9401     @Override
9402     public void setTaskResizeable(int taskId, int resizeableMode) {
9403         synchronized (this) {
9404             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9405                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9406             if (task == null) {
9407                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9408                 return;
9409             }
9410             if (task.mResizeMode != resizeableMode) {
9411                 task.mResizeMode = resizeableMode;
9412                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9413                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9414                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9415             }
9416         }
9417     }
9418
9419     @Override
9420     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9421         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9422         long ident = Binder.clearCallingIdentity();
9423         try {
9424             synchronized (this) {
9425                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9426                 if (task == null) {
9427                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9428                     return;
9429                 }
9430                 int stackId = task.stack.mStackId;
9431                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9432                 // in crop windows resize mode or if the task size is affected by the docked stack
9433                 // changing size. No need to update configuration.
9434                 if (bounds != null && task.inCropWindowsResizeMode()
9435                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9436                     mWindowManager.scrollTask(task.taskId, bounds);
9437                     return;
9438                 }
9439
9440                 // Place the task in the right stack if it isn't there already based on
9441                 // the requested bounds.
9442                 // The stack transition logic is:
9443                 // - a null bounds on a freeform task moves that task to fullscreen
9444                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9445                 //   that task to freeform
9446                 // - otherwise the task is not moved
9447                 if (!StackId.isTaskResizeAllowed(stackId)) {
9448                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9449                 }
9450                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9451                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9452                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9453                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9454                 }
9455                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9456                 if (stackId != task.stack.mStackId) {
9457                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9458                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9459                     preserveWindow = false;
9460                 }
9461
9462                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9463                         false /* deferResume */);
9464             }
9465         } finally {
9466             Binder.restoreCallingIdentity(ident);
9467         }
9468     }
9469
9470     @Override
9471     public Rect getTaskBounds(int taskId) {
9472         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9473         long ident = Binder.clearCallingIdentity();
9474         Rect rect = new Rect();
9475         try {
9476             synchronized (this) {
9477                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9478                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9479                 if (task == null) {
9480                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9481                     return rect;
9482                 }
9483                 if (task.stack != null) {
9484                     // Return the bounds from window manager since it will be adjusted for various
9485                     // things like the presense of a docked stack for tasks that aren't resizeable.
9486                     mWindowManager.getTaskBounds(task.taskId, rect);
9487                 } else {
9488                     // Task isn't in window manager yet since it isn't associated with a stack.
9489                     // Return the persist value from activity manager
9490                     if (task.mBounds != null) {
9491                         rect.set(task.mBounds);
9492                     } else if (task.mLastNonFullscreenBounds != null) {
9493                         rect.set(task.mLastNonFullscreenBounds);
9494                     }
9495                 }
9496             }
9497         } finally {
9498             Binder.restoreCallingIdentity(ident);
9499         }
9500         return rect;
9501     }
9502
9503     @Override
9504     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9505         if (userId != UserHandle.getCallingUserId()) {
9506             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9507                     "getTaskDescriptionIcon");
9508         }
9509         final File passedIconFile = new File(filePath);
9510         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9511                 passedIconFile.getName());
9512         if (!legitIconFile.getPath().equals(filePath)
9513                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9514             throw new IllegalArgumentException("Bad file path: " + filePath
9515                     + " passed for userId " + userId);
9516         }
9517         return mRecentTasks.getTaskDescriptionIcon(filePath);
9518     }
9519
9520     @Override
9521     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9522             throws RemoteException {
9523         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9524                 opts.getCustomInPlaceResId() == 0) {
9525             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9526                     "with valid animation");
9527         }
9528         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9529         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9530                 opts.getCustomInPlaceResId());
9531         mWindowManager.executeAppTransition();
9532     }
9533
9534     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9535             boolean removeFromRecents) {
9536         if (removeFromRecents) {
9537             mRecentTasks.remove(tr);
9538             tr.removedFromRecents();
9539         }
9540         ComponentName component = tr.getBaseIntent().getComponent();
9541         if (component == null) {
9542             Slog.w(TAG, "No component for base intent of task: " + tr);
9543             return;
9544         }
9545
9546         // Find any running services associated with this app and stop if needed.
9547         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9548
9549         if (!killProcess) {
9550             return;
9551         }
9552
9553         // Determine if the process(es) for this task should be killed.
9554         final String pkg = component.getPackageName();
9555         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9556         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9557         for (int i = 0; i < pmap.size(); i++) {
9558
9559             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9560             for (int j = 0; j < uids.size(); j++) {
9561                 ProcessRecord proc = uids.valueAt(j);
9562                 if (proc.userId != tr.userId) {
9563                     // Don't kill process for a different user.
9564                     continue;
9565                 }
9566                 if (proc == mHomeProcess) {
9567                     // Don't kill the home process along with tasks from the same package.
9568                     continue;
9569                 }
9570                 if (!proc.pkgList.containsKey(pkg)) {
9571                     // Don't kill process that is not associated with this task.
9572                     continue;
9573                 }
9574
9575                 for (int k = 0; k < proc.activities.size(); k++) {
9576                     TaskRecord otherTask = proc.activities.get(k).task;
9577                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9578                         // Don't kill process(es) that has an activity in a different task that is
9579                         // also in recents.
9580                         return;
9581                     }
9582                 }
9583
9584                 if (proc.foregroundServices) {
9585                     // Don't kill process(es) with foreground service.
9586                     return;
9587                 }
9588
9589                 // Add process to kill list.
9590                 procsToKill.add(proc);
9591             }
9592         }
9593
9594         // Kill the running processes.
9595         for (int i = 0; i < procsToKill.size(); i++) {
9596             ProcessRecord pr = procsToKill.get(i);
9597             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9598                     && pr.curReceiver == null) {
9599                 pr.kill("remove task", true);
9600             } else {
9601                 // We delay killing processes that are not in the background or running a receiver.
9602                 pr.waitingToKill = "remove task";
9603             }
9604         }
9605     }
9606
9607     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9608         // Remove all tasks with activities in the specified package from the list of recent tasks
9609         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9610             TaskRecord tr = mRecentTasks.get(i);
9611             if (tr.userId != userId) continue;
9612
9613             ComponentName cn = tr.intent.getComponent();
9614             if (cn != null && cn.getPackageName().equals(packageName)) {
9615                 // If the package name matches, remove the task.
9616                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9617             }
9618         }
9619     }
9620
9621     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9622             int userId) {
9623
9624         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9625             TaskRecord tr = mRecentTasks.get(i);
9626             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9627                 continue;
9628             }
9629
9630             ComponentName cn = tr.intent.getComponent();
9631             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9632                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9633             if (sameComponent) {
9634                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9635             }
9636         }
9637     }
9638
9639     /**
9640      * Removes the task with the specified task id.
9641      *
9642      * @param taskId Identifier of the task to be removed.
9643      * @param killProcess Kill any process associated with the task if possible.
9644      * @param removeFromRecents Whether to also remove the task from recents.
9645      * @return Returns true if the given task was found and removed.
9646      */
9647     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9648             boolean removeFromRecents) {
9649         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9650                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9651         if (tr != null) {
9652             tr.removeTaskActivitiesLocked();
9653             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9654             if (tr.isPersistable) {
9655                 notifyTaskPersisterLocked(null, true);
9656             }
9657             return true;
9658         }
9659         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9660         return false;
9661     }
9662
9663     @Override
9664     public void removeStack(int stackId) {
9665         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9666         if (stackId == HOME_STACK_ID) {
9667             throw new IllegalArgumentException("Removing home stack is not allowed.");
9668         }
9669
9670         synchronized (this) {
9671             final long ident = Binder.clearCallingIdentity();
9672             try {
9673                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9674                 if (stack == null) {
9675                     return;
9676                 }
9677                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9678                 for (int i = tasks.size() - 1; i >= 0; i--) {
9679                     removeTaskByIdLocked(
9680                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9681                 }
9682             } finally {
9683                 Binder.restoreCallingIdentity(ident);
9684             }
9685         }
9686     }
9687
9688     @Override
9689     public boolean removeTask(int taskId) {
9690         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9691         synchronized (this) {
9692             final long ident = Binder.clearCallingIdentity();
9693             try {
9694                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9695             } finally {
9696                 Binder.restoreCallingIdentity(ident);
9697             }
9698         }
9699     }
9700
9701     /**
9702      * TODO: Add mController hook
9703      */
9704     @Override
9705     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9706         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9707
9708         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9709         synchronized(this) {
9710             moveTaskToFrontLocked(taskId, flags, bOptions);
9711         }
9712     }
9713
9714     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9715         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9716
9717         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9718                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9719             ActivityOptions.abort(options);
9720             return;
9721         }
9722         final long origId = Binder.clearCallingIdentity();
9723         try {
9724             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9725             if (task == null) {
9726                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9727                 return;
9728             }
9729             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9730                 mStackSupervisor.showLockTaskToast();
9731                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9732                 return;
9733             }
9734             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9735             if (prev != null && prev.isRecentsActivity()) {
9736                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9737             }
9738             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9739                     false /* forceNonResizable */);
9740         } finally {
9741             Binder.restoreCallingIdentity(origId);
9742         }
9743         ActivityOptions.abort(options);
9744     }
9745
9746     /**
9747      * Moves an activity, and all of the other activities within the same task, to the bottom
9748      * of the history stack.  The activity's order within the task is unchanged.
9749      *
9750      * @param token A reference to the activity we wish to move
9751      * @param nonRoot If false then this only works if the activity is the root
9752      *                of a task; if true it will work for any activity in a task.
9753      * @return Returns true if the move completed, false if not.
9754      */
9755     @Override
9756     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9757         enforceNotIsolatedCaller("moveActivityTaskToBack");
9758         synchronized(this) {
9759             final long origId = Binder.clearCallingIdentity();
9760             try {
9761                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9762                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9763                 if (task != null) {
9764                     if (mStackSupervisor.isLockedTask(task)) {
9765                         mStackSupervisor.showLockTaskToast();
9766                         return false;
9767                     }
9768                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9769                 }
9770             } finally {
9771                 Binder.restoreCallingIdentity(origId);
9772             }
9773         }
9774         return false;
9775     }
9776
9777     @Override
9778     public void moveTaskBackwards(int task) {
9779         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9780                 "moveTaskBackwards()");
9781
9782         synchronized(this) {
9783             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9784                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9785                 return;
9786             }
9787             final long origId = Binder.clearCallingIdentity();
9788             moveTaskBackwardsLocked(task);
9789             Binder.restoreCallingIdentity(origId);
9790         }
9791     }
9792
9793     private final void moveTaskBackwardsLocked(int task) {
9794         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9795     }
9796
9797     @Override
9798     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9799             IActivityContainerCallback callback) throws RemoteException {
9800         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9801         synchronized (this) {
9802             if (parentActivityToken == null) {
9803                 throw new IllegalArgumentException("parent token must not be null");
9804             }
9805             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9806             if (r == null) {
9807                 return null;
9808             }
9809             if (callback == null) {
9810                 throw new IllegalArgumentException("callback must not be null");
9811             }
9812             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9813         }
9814     }
9815
9816     @Override
9817     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9818         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9819         synchronized (this) {
9820             mStackSupervisor.deleteActivityContainer(container);
9821         }
9822     }
9823
9824     @Override
9825     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9826         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9827         synchronized (this) {
9828             final int stackId = mStackSupervisor.getNextStackId();
9829             final ActivityStack stack =
9830                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9831             if (stack == null) {
9832                 return null;
9833             }
9834             return stack.mActivityContainer;
9835         }
9836     }
9837
9838     @Override
9839     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9840         synchronized (this) {
9841             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9842             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9843                 return stack.mActivityContainer.getDisplayId();
9844             }
9845             return Display.DEFAULT_DISPLAY;
9846         }
9847     }
9848
9849     @Override
9850     public int getActivityStackId(IBinder token) throws RemoteException {
9851         synchronized (this) {
9852             ActivityStack stack = ActivityRecord.getStackLocked(token);
9853             if (stack == null) {
9854                 return INVALID_STACK_ID;
9855             }
9856             return stack.mStackId;
9857         }
9858     }
9859
9860     @Override
9861     public void exitFreeformMode(IBinder token) throws RemoteException {
9862         synchronized (this) {
9863             long ident = Binder.clearCallingIdentity();
9864             try {
9865                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9866                 if (r == null) {
9867                     throw new IllegalArgumentException(
9868                             "exitFreeformMode: No activity record matching token=" + token);
9869                 }
9870                 final ActivityStack stack = r.getStackLocked(token);
9871                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9872                     throw new IllegalStateException(
9873                             "exitFreeformMode: You can only go fullscreen from freeform.");
9874                 }
9875                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9876                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9877                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9878             } finally {
9879                 Binder.restoreCallingIdentity(ident);
9880             }
9881         }
9882     }
9883
9884     @Override
9885     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9886         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9887         if (stackId == HOME_STACK_ID) {
9888             throw new IllegalArgumentException(
9889                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9890         }
9891         synchronized (this) {
9892             long ident = Binder.clearCallingIdentity();
9893             try {
9894                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9895                         + " to stackId=" + stackId + " toTop=" + toTop);
9896                 if (stackId == DOCKED_STACK_ID) {
9897                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9898                             null /* initialBounds */);
9899                 }
9900                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9901                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9902                 if (result && stackId == DOCKED_STACK_ID) {
9903                     // If task moved to docked stack - show recents if needed.
9904                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9905                             "moveTaskToDockedStack");
9906                 }
9907             } finally {
9908                 Binder.restoreCallingIdentity(ident);
9909             }
9910         }
9911     }
9912
9913     @Override
9914     public void swapDockedAndFullscreenStack() throws RemoteException {
9915         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9916         synchronized (this) {
9917             long ident = Binder.clearCallingIdentity();
9918             try {
9919                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9920                         FULLSCREEN_WORKSPACE_STACK_ID);
9921                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9922                         : null;
9923                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9924                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9925                         : null;
9926                 if (topTask == null || tasks == null || tasks.size() == 0) {
9927                     Slog.w(TAG,
9928                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9929                     return;
9930                 }
9931
9932                 // TODO: App transition
9933                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9934
9935                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9936                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9937                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9938                         ANIMATE, true /* deferResume */);
9939                 final int size = tasks.size();
9940                 for (int i = 0; i < size; i++) {
9941                     final int id = tasks.get(i).taskId;
9942                     if (id == topTask.taskId) {
9943                         continue;
9944                     }
9945                     mStackSupervisor.moveTaskToStackLocked(id,
9946                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9947                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9948                 }
9949
9950                 // Because we deferred the resume, to avoid conflicts with stack switches while
9951                 // resuming, we need to do it after all the tasks are moved.
9952                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9953                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9954
9955                 mWindowManager.executeAppTransition();
9956             } finally {
9957                 Binder.restoreCallingIdentity(ident);
9958             }
9959         }
9960     }
9961
9962     /**
9963      * Moves the input task to the docked stack.
9964      *
9965      * @param taskId Id of task to move.
9966      * @param createMode The mode the docked stack should be created in if it doesn't exist
9967      *                   already. See
9968      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9969      *                   and
9970      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9971      * @param toTop If the task and stack should be moved to the top.
9972      * @param animate Whether we should play an animation for the moving the task
9973      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9974      *                      docked stack. Pass {@code null} to use default bounds.
9975      */
9976     @Override
9977     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9978             Rect initialBounds, boolean moveHomeStackFront) {
9979         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9980         synchronized (this) {
9981             long ident = Binder.clearCallingIdentity();
9982             try {
9983                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9984                         + " to createMode=" + createMode + " toTop=" + toTop);
9985                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9986                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9987                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9988                         animate, DEFER_RESUME);
9989                 if (moved) {
9990                     if (moveHomeStackFront) {
9991                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9992                     }
9993                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9994                 }
9995                 return moved;
9996             } finally {
9997                 Binder.restoreCallingIdentity(ident);
9998             }
9999         }
10000     }
10001
10002     /**
10003      * Moves the top activity in the input stackId to the pinned stack.
10004      *
10005      * @param stackId Id of stack to move the top activity to pinned stack.
10006      * @param bounds Bounds to use for pinned stack.
10007      *
10008      * @return True if the top activity of the input stack was successfully moved to the pinned
10009      *          stack.
10010      */
10011     @Override
10012     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10013         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10014         synchronized (this) {
10015             if (!mSupportsPictureInPicture) {
10016                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10017                         + "Device doesn't support picture-in-pciture mode");
10018             }
10019
10020             long ident = Binder.clearCallingIdentity();
10021             try {
10022                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10023             } finally {
10024                 Binder.restoreCallingIdentity(ident);
10025             }
10026         }
10027     }
10028
10029     @Override
10030     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10031             boolean preserveWindows, boolean animate, int animationDuration) {
10032         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10033         long ident = Binder.clearCallingIdentity();
10034         try {
10035             synchronized (this) {
10036                 if (animate) {
10037                     if (stackId == PINNED_STACK_ID) {
10038                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10039                     } else {
10040                         throw new IllegalArgumentException("Stack: " + stackId
10041                                 + " doesn't support animated resize.");
10042                     }
10043                 } else {
10044                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10045                             null /* tempTaskInsetBounds */, preserveWindows,
10046                             allowResizeInDockedMode, !DEFER_RESUME);
10047                 }
10048             }
10049         } finally {
10050             Binder.restoreCallingIdentity(ident);
10051         }
10052     }
10053
10054     @Override
10055     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10056             Rect tempDockedTaskInsetBounds,
10057             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10058         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10059                 "resizeDockedStack()");
10060         long ident = Binder.clearCallingIdentity();
10061         try {
10062             synchronized (this) {
10063                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10064                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10065                         PRESERVE_WINDOWS);
10066             }
10067         } finally {
10068             Binder.restoreCallingIdentity(ident);
10069         }
10070     }
10071
10072     @Override
10073     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10074         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10075                 "resizePinnedStack()");
10076         final long ident = Binder.clearCallingIdentity();
10077         try {
10078             synchronized (this) {
10079                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10080             }
10081         } finally {
10082             Binder.restoreCallingIdentity(ident);
10083         }
10084     }
10085
10086     @Override
10087     public void positionTaskInStack(int taskId, int stackId, int position) {
10088         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10089         if (stackId == HOME_STACK_ID) {
10090             throw new IllegalArgumentException(
10091                     "positionTaskInStack: Attempt to change the position of task "
10092                     + taskId + " in/to home stack");
10093         }
10094         synchronized (this) {
10095             long ident = Binder.clearCallingIdentity();
10096             try {
10097                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10098                         "positionTaskInStack: positioning task=" + taskId
10099                         + " in stackId=" + stackId + " at position=" + position);
10100                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10101             } finally {
10102                 Binder.restoreCallingIdentity(ident);
10103             }
10104         }
10105     }
10106
10107     @Override
10108     public List<StackInfo> getAllStackInfos() {
10109         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10110         long ident = Binder.clearCallingIdentity();
10111         try {
10112             synchronized (this) {
10113                 return mStackSupervisor.getAllStackInfosLocked();
10114             }
10115         } finally {
10116             Binder.restoreCallingIdentity(ident);
10117         }
10118     }
10119
10120     @Override
10121     public StackInfo getStackInfo(int stackId) {
10122         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10123         long ident = Binder.clearCallingIdentity();
10124         try {
10125             synchronized (this) {
10126                 return mStackSupervisor.getStackInfoLocked(stackId);
10127             }
10128         } finally {
10129             Binder.restoreCallingIdentity(ident);
10130         }
10131     }
10132
10133     @Override
10134     public boolean isInHomeStack(int taskId) {
10135         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10136         long ident = Binder.clearCallingIdentity();
10137         try {
10138             synchronized (this) {
10139                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10140                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10141                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10142             }
10143         } finally {
10144             Binder.restoreCallingIdentity(ident);
10145         }
10146     }
10147
10148     @Override
10149     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10150         synchronized(this) {
10151             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10152         }
10153     }
10154
10155     @Override
10156     public void updateDeviceOwner(String packageName) {
10157         final int callingUid = Binder.getCallingUid();
10158         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10159             throw new SecurityException("updateDeviceOwner called from non-system process");
10160         }
10161         synchronized (this) {
10162             mDeviceOwnerName = packageName;
10163         }
10164     }
10165
10166     @Override
10167     public void updateLockTaskPackages(int userId, String[] packages) {
10168         final int callingUid = Binder.getCallingUid();
10169         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10170             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10171                     "updateLockTaskPackages()");
10172         }
10173         synchronized (this) {
10174             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10175                     Arrays.toString(packages));
10176             mLockTaskPackages.put(userId, packages);
10177             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10178         }
10179     }
10180
10181
10182     void startLockTaskModeLocked(TaskRecord task) {
10183         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10184         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10185             return;
10186         }
10187
10188         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10189         // is initiated by system after the pinning request was shown and locked mode is initiated
10190         // by an authorized app directly
10191         final int callingUid = Binder.getCallingUid();
10192         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10193         long ident = Binder.clearCallingIdentity();
10194         try {
10195             if (!isSystemInitiated) {
10196                 task.mLockTaskUid = callingUid;
10197                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10198                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10199                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10200                     StatusBarManagerInternal statusBarManager =
10201                             LocalServices.getService(StatusBarManagerInternal.class);
10202                     if (statusBarManager != null) {
10203                         statusBarManager.showScreenPinningRequest(task.taskId);
10204                     }
10205                     return;
10206                 }
10207
10208                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10209                 if (stack == null || task != stack.topTask()) {
10210                     throw new IllegalArgumentException("Invalid task, not in foreground");
10211                 }
10212             }
10213             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10214                     "Locking fully");
10215             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10216                     ActivityManager.LOCK_TASK_MODE_PINNED :
10217                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10218                     "startLockTask", true);
10219         } finally {
10220             Binder.restoreCallingIdentity(ident);
10221         }
10222     }
10223
10224     @Override
10225     public void startLockTaskMode(int taskId) {
10226         synchronized (this) {
10227             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10228             if (task != null) {
10229                 startLockTaskModeLocked(task);
10230             }
10231         }
10232     }
10233
10234     @Override
10235     public void startLockTaskMode(IBinder token) {
10236         synchronized (this) {
10237             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10238             if (r == null) {
10239                 return;
10240             }
10241             final TaskRecord task = r.task;
10242             if (task != null) {
10243                 startLockTaskModeLocked(task);
10244             }
10245         }
10246     }
10247
10248     @Override
10249     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10250         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10251         // This makes inner call to look as if it was initiated by system.
10252         long ident = Binder.clearCallingIdentity();
10253         try {
10254             synchronized (this) {
10255                 startLockTaskMode(taskId);
10256             }
10257         } finally {
10258             Binder.restoreCallingIdentity(ident);
10259         }
10260     }
10261
10262     @Override
10263     public void stopLockTaskMode() {
10264         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10265         if (lockTask == null) {
10266             // Our work here is done.
10267             return;
10268         }
10269
10270         final int callingUid = Binder.getCallingUid();
10271         final int lockTaskUid = lockTask.mLockTaskUid;
10272         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10273         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10274             // Done.
10275             return;
10276         } else {
10277             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10278             // It is possible lockTaskMode was started by the system process because
10279             // android:lockTaskMode is set to a locking value in the application manifest
10280             // instead of the app calling startLockTaskMode. In this case
10281             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10282             // {@link TaskRecord.effectiveUid} instead. Also caller with
10283             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10284             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10285                     && callingUid != lockTaskUid
10286                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10287                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10288                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10289             }
10290         }
10291         long ident = Binder.clearCallingIdentity();
10292         try {
10293             Log.d(TAG, "stopLockTaskMode");
10294             // Stop lock task
10295             synchronized (this) {
10296                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10297                         "stopLockTask", true);
10298             }
10299             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10300             if (tm != null) {
10301                 tm.showInCallScreen(false);
10302             }
10303         } finally {
10304             Binder.restoreCallingIdentity(ident);
10305         }
10306     }
10307
10308     /**
10309      * This API should be called by SystemUI only when user perform certain action to dismiss
10310      * lock task mode. We should only dismiss pinned lock task mode in this case.
10311      */
10312     @Override
10313     public void stopSystemLockTaskMode() throws RemoteException {
10314         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10315             stopLockTaskMode();
10316         } else {
10317             mStackSupervisor.showLockTaskToast();
10318         }
10319     }
10320
10321     @Override
10322     public boolean isInLockTaskMode() {
10323         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10324     }
10325
10326     @Override
10327     public int getLockTaskModeState() {
10328         synchronized (this) {
10329             return mStackSupervisor.getLockTaskModeState();
10330         }
10331     }
10332
10333     @Override
10334     public void showLockTaskEscapeMessage(IBinder token) {
10335         synchronized (this) {
10336             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10337             if (r == null) {
10338                 return;
10339             }
10340             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10341         }
10342     }
10343
10344     // =========================================================
10345     // CONTENT PROVIDERS
10346     // =========================================================
10347
10348     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10349         List<ProviderInfo> providers = null;
10350         try {
10351             providers = AppGlobals.getPackageManager()
10352                     .queryContentProviders(app.processName, app.uid,
10353                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10354                                     | MATCH_DEBUG_TRIAGED_MISSING)
10355                     .getList();
10356         } catch (RemoteException ex) {
10357         }
10358         if (DEBUG_MU) Slog.v(TAG_MU,
10359                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10360         int userId = app.userId;
10361         if (providers != null) {
10362             int N = providers.size();
10363             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10364             for (int i=0; i<N; i++) {
10365                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10366                 ProviderInfo cpi =
10367                     (ProviderInfo)providers.get(i);
10368                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10369                         cpi.name, cpi.flags);
10370                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10371                     // This is a singleton provider, but a user besides the
10372                     // default user is asking to initialize a process it runs
10373                     // in...  well, no, it doesn't actually run in this process,
10374                     // it runs in the process of the default user.  Get rid of it.
10375                     providers.remove(i);
10376                     N--;
10377                     i--;
10378                     continue;
10379                 }
10380
10381                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10382                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10383                 if (cpr == null) {
10384                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10385                     mProviderMap.putProviderByClass(comp, cpr);
10386                 }
10387                 if (DEBUG_MU) Slog.v(TAG_MU,
10388                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10389                 app.pubProviders.put(cpi.name, cpr);
10390                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10391                     // Don't add this if it is a platform component that is marked
10392                     // to run in multiple processes, because this is actually
10393                     // part of the framework so doesn't make sense to track as a
10394                     // separate apk in the process.
10395                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10396                             mProcessStats);
10397                 }
10398                 notifyPackageUse(cpi.applicationInfo.packageName,
10399                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10400             }
10401         }
10402         return providers;
10403     }
10404
10405     /**
10406      * Check if the calling UID has a possible chance at accessing the provider
10407      * at the given authority and user.
10408      */
10409     public String checkContentProviderAccess(String authority, int userId) {
10410         if (userId == UserHandle.USER_ALL) {
10411             mContext.enforceCallingOrSelfPermission(
10412                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10413             userId = UserHandle.getCallingUserId();
10414         }
10415
10416         ProviderInfo cpi = null;
10417         try {
10418             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10419                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10420                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10421                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10422                     userId);
10423         } catch (RemoteException ignored) {
10424         }
10425         if (cpi == null) {
10426             // TODO: make this an outright failure in a future platform release;
10427             // until then anonymous content notifications are unprotected
10428             //return "Failed to find provider " + authority + " for user " + userId;
10429             return null;
10430         }
10431
10432         ProcessRecord r = null;
10433         synchronized (mPidsSelfLocked) {
10434             r = mPidsSelfLocked.get(Binder.getCallingPid());
10435         }
10436         if (r == null) {
10437             return "Failed to find PID " + Binder.getCallingPid();
10438         }
10439
10440         synchronized (this) {
10441             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10442         }
10443     }
10444
10445     /**
10446      * Check if {@link ProcessRecord} has a possible chance at accessing the
10447      * given {@link ProviderInfo}. Final permission checking is always done
10448      * in {@link ContentProvider}.
10449      */
10450     private final String checkContentProviderPermissionLocked(
10451             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10452         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10453         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10454         boolean checkedGrants = false;
10455         if (checkUser) {
10456             // Looking for cross-user grants before enforcing the typical cross-users permissions
10457             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10458             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10459                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10460                     return null;
10461                 }
10462                 checkedGrants = true;
10463             }
10464             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10465                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10466             if (userId != tmpTargetUserId) {
10467                 // When we actually went to determine the final targer user ID, this ended
10468                 // up different than our initial check for the authority.  This is because
10469                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10470                 // SELF.  So we need to re-check the grants again.
10471                 checkedGrants = false;
10472             }
10473         }
10474         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10475                 cpi.applicationInfo.uid, cpi.exported)
10476                 == PackageManager.PERMISSION_GRANTED) {
10477             return null;
10478         }
10479         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10480                 cpi.applicationInfo.uid, cpi.exported)
10481                 == PackageManager.PERMISSION_GRANTED) {
10482             return null;
10483         }
10484
10485         PathPermission[] pps = cpi.pathPermissions;
10486         if (pps != null) {
10487             int i = pps.length;
10488             while (i > 0) {
10489                 i--;
10490                 PathPermission pp = pps[i];
10491                 String pprperm = pp.getReadPermission();
10492                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10493                         cpi.applicationInfo.uid, cpi.exported)
10494                         == PackageManager.PERMISSION_GRANTED) {
10495                     return null;
10496                 }
10497                 String ppwperm = pp.getWritePermission();
10498                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10499                         cpi.applicationInfo.uid, cpi.exported)
10500                         == PackageManager.PERMISSION_GRANTED) {
10501                     return null;
10502                 }
10503             }
10504         }
10505         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10506             return null;
10507         }
10508
10509         String msg;
10510         if (!cpi.exported) {
10511             msg = "Permission Denial: opening provider " + cpi.name
10512                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10513                     + ", uid=" + callingUid + ") that is not exported from uid "
10514                     + cpi.applicationInfo.uid;
10515         } else {
10516             msg = "Permission Denial: opening provider " + cpi.name
10517                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10518                     + ", uid=" + callingUid + ") requires "
10519                     + cpi.readPermission + " or " + cpi.writePermission;
10520         }
10521         Slog.w(TAG, msg);
10522         return msg;
10523     }
10524
10525     /**
10526      * Returns if the ContentProvider has granted a uri to callingUid
10527      */
10528     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10529         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10530         if (perms != null) {
10531             for (int i=perms.size()-1; i>=0; i--) {
10532                 GrantUri grantUri = perms.keyAt(i);
10533                 if (grantUri.sourceUserId == userId || !checkUser) {
10534                     if (matchesProvider(grantUri.uri, cpi)) {
10535                         return true;
10536                     }
10537                 }
10538             }
10539         }
10540         return false;
10541     }
10542
10543     /**
10544      * Returns true if the uri authority is one of the authorities specified in the provider.
10545      */
10546     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10547         String uriAuth = uri.getAuthority();
10548         String cpiAuth = cpi.authority;
10549         if (cpiAuth.indexOf(';') == -1) {
10550             return cpiAuth.equals(uriAuth);
10551         }
10552         String[] cpiAuths = cpiAuth.split(";");
10553         int length = cpiAuths.length;
10554         for (int i = 0; i < length; i++) {
10555             if (cpiAuths[i].equals(uriAuth)) return true;
10556         }
10557         return false;
10558     }
10559
10560     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10561             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10562         if (r != null) {
10563             for (int i=0; i<r.conProviders.size(); i++) {
10564                 ContentProviderConnection conn = r.conProviders.get(i);
10565                 if (conn.provider == cpr) {
10566                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10567                             "Adding provider requested by "
10568                             + r.processName + " from process "
10569                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10570                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10571                     if (stable) {
10572                         conn.stableCount++;
10573                         conn.numStableIncs++;
10574                     } else {
10575                         conn.unstableCount++;
10576                         conn.numUnstableIncs++;
10577                     }
10578                     return conn;
10579                 }
10580             }
10581             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10582             if (stable) {
10583                 conn.stableCount = 1;
10584                 conn.numStableIncs = 1;
10585             } else {
10586                 conn.unstableCount = 1;
10587                 conn.numUnstableIncs = 1;
10588             }
10589             cpr.connections.add(conn);
10590             r.conProviders.add(conn);
10591             startAssociationLocked(r.uid, r.processName, r.curProcState,
10592                     cpr.uid, cpr.name, cpr.info.processName);
10593             return conn;
10594         }
10595         cpr.addExternalProcessHandleLocked(externalProcessToken);
10596         return null;
10597     }
10598
10599     boolean decProviderCountLocked(ContentProviderConnection conn,
10600             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10601         if (conn != null) {
10602             cpr = conn.provider;
10603             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10604                     "Removing provider requested by "
10605                     + conn.client.processName + " from process "
10606                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10607                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10608             if (stable) {
10609                 conn.stableCount--;
10610             } else {
10611                 conn.unstableCount--;
10612             }
10613             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10614                 cpr.connections.remove(conn);
10615                 conn.client.conProviders.remove(conn);
10616                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10617                     // The client is more important than last activity -- note the time this
10618                     // is happening, so we keep the old provider process around a bit as last
10619                     // activity to avoid thrashing it.
10620                     if (cpr.proc != null) {
10621                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10622                     }
10623                 }
10624                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10625                 return true;
10626             }
10627             return false;
10628         }
10629         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10630         return false;
10631     }
10632
10633     private void checkTime(long startTime, String where) {
10634         long now = SystemClock.uptimeMillis();
10635         if ((now-startTime) > 50) {
10636             // If we are taking more than 50ms, log about it.
10637             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10638         }
10639     }
10640
10641     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10642             PROC_SPACE_TERM,
10643             PROC_SPACE_TERM|PROC_PARENS,
10644             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10645     };
10646
10647     private final long[] mProcessStateStatsLongs = new long[1];
10648
10649     boolean isProcessAliveLocked(ProcessRecord proc) {
10650         if (proc.procStatFile == null) {
10651             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10652         }
10653         mProcessStateStatsLongs[0] = 0;
10654         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10655                 mProcessStateStatsLongs, null)) {
10656             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10657             return false;
10658         }
10659         final long state = mProcessStateStatsLongs[0];
10660         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10661                 + (char)state);
10662         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10663     }
10664
10665     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10666             String name, IBinder token, boolean stable, int userId) {
10667         ContentProviderRecord cpr;
10668         ContentProviderConnection conn = null;
10669         ProviderInfo cpi = null;
10670
10671         synchronized(this) {
10672             long startTime = SystemClock.uptimeMillis();
10673
10674             ProcessRecord r = null;
10675             if (caller != null) {
10676                 r = getRecordForAppLocked(caller);
10677                 if (r == null) {
10678                     throw new SecurityException(
10679                             "Unable to find app for caller " + caller
10680                           + " (pid=" + Binder.getCallingPid()
10681                           + ") when getting content provider " + name);
10682                 }
10683             }
10684
10685             boolean checkCrossUser = true;
10686
10687             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10688
10689             // First check if this content provider has been published...
10690             cpr = mProviderMap.getProviderByName(name, userId);
10691             // If that didn't work, check if it exists for user 0 and then
10692             // verify that it's a singleton provider before using it.
10693             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10694                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10695                 if (cpr != null) {
10696                     cpi = cpr.info;
10697                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10698                             cpi.name, cpi.flags)
10699                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10700                         userId = UserHandle.USER_SYSTEM;
10701                         checkCrossUser = false;
10702                     } else {
10703                         cpr = null;
10704                         cpi = null;
10705                     }
10706                 }
10707             }
10708
10709             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10710             if (providerRunning) {
10711                 cpi = cpr.info;
10712                 String msg;
10713                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10714                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10715                         != null) {
10716                     throw new SecurityException(msg);
10717                 }
10718                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10719
10720                 if (r != null && cpr.canRunHere(r)) {
10721                     // This provider has been published or is in the process
10722                     // of being published...  but it is also allowed to run
10723                     // in the caller's process, so don't make a connection
10724                     // and just let the caller instantiate its own instance.
10725                     ContentProviderHolder holder = cpr.newHolder(null);
10726                     // don't give caller the provider object, it needs
10727                     // to make its own.
10728                     holder.provider = null;
10729                     return holder;
10730                 }
10731
10732                 final long origId = Binder.clearCallingIdentity();
10733
10734                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10735
10736                 // In this case the provider instance already exists, so we can
10737                 // return it right away.
10738                 conn = incProviderCountLocked(r, cpr, token, stable);
10739                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10740                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10741                         // If this is a perceptible app accessing the provider,
10742                         // make sure to count it as being accessed and thus
10743                         // back up on the LRU list.  This is good because
10744                         // content providers are often expensive to start.
10745                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10746                         updateLruProcessLocked(cpr.proc, false, null);
10747                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10748                     }
10749                 }
10750
10751                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10752                 final int verifiedAdj = cpr.proc.verifiedAdj;
10753                 boolean success = updateOomAdjLocked(cpr.proc);
10754                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10755                 // if the process has been successfully adjusted.  So to reduce races with
10756                 // it, we will check whether the process still exists.  Note that this doesn't
10757                 // completely get rid of races with LMK killing the process, but should make
10758                 // them much smaller.
10759                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10760                     success = false;
10761                 }
10762                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10763                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10764                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10765                 // NOTE: there is still a race here where a signal could be
10766                 // pending on the process even though we managed to update its
10767                 // adj level.  Not sure what to do about this, but at least
10768                 // the race is now smaller.
10769                 if (!success) {
10770                     // Uh oh...  it looks like the provider's process
10771                     // has been killed on us.  We need to wait for a new
10772                     // process to be started, and make sure its death
10773                     // doesn't kill our process.
10774                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10775                             + " is crashing; detaching " + r);
10776                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10777                     checkTime(startTime, "getContentProviderImpl: before appDied");
10778                     appDiedLocked(cpr.proc);
10779                     checkTime(startTime, "getContentProviderImpl: after appDied");
10780                     if (!lastRef) {
10781                         // This wasn't the last ref our process had on
10782                         // the provider...  we have now been killed, bail.
10783                         return null;
10784                     }
10785                     providerRunning = false;
10786                     conn = null;
10787                 } else {
10788                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10789                 }
10790
10791                 Binder.restoreCallingIdentity(origId);
10792             }
10793
10794             if (!providerRunning) {
10795                 try {
10796                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10797                     cpi = AppGlobals.getPackageManager().
10798                         resolveContentProvider(name,
10799                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10800                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10801                 } catch (RemoteException ex) {
10802                 }
10803                 if (cpi == null) {
10804                     return null;
10805                 }
10806                 // If the provider is a singleton AND
10807                 // (it's a call within the same user || the provider is a
10808                 // privileged app)
10809                 // Then allow connecting to the singleton provider
10810                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10811                         cpi.name, cpi.flags)
10812                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10813                 if (singleton) {
10814                     userId = UserHandle.USER_SYSTEM;
10815                 }
10816                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10817                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10818
10819                 String msg;
10820                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10821                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10822                         != null) {
10823                     throw new SecurityException(msg);
10824                 }
10825                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10826
10827                 if (!mProcessesReady
10828                         && !cpi.processName.equals("system")) {
10829                     // If this content provider does not run in the system
10830                     // process, and the system is not yet ready to run other
10831                     // processes, then fail fast instead of hanging.
10832                     throw new IllegalArgumentException(
10833                             "Attempt to launch content provider before system ready");
10834                 }
10835
10836                 // Make sure that the user who owns this provider is running.  If not,
10837                 // we don't want to allow it to run.
10838                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10839                     Slog.w(TAG, "Unable to launch app "
10840                             + cpi.applicationInfo.packageName + "/"
10841                             + cpi.applicationInfo.uid + " for provider "
10842                             + name + ": user " + userId + " is stopped");
10843                     return null;
10844                 }
10845
10846                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10847                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10848                 cpr = mProviderMap.getProviderByClass(comp, userId);
10849                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10850                 final boolean firstClass = cpr == null;
10851                 if (firstClass) {
10852                     final long ident = Binder.clearCallingIdentity();
10853
10854                     // If permissions need a review before any of the app components can run,
10855                     // we return no provider and launch a review activity if the calling app
10856                     // is in the foreground.
10857                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10858                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10859                             return null;
10860                         }
10861                     }
10862
10863                     try {
10864                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10865                         ApplicationInfo ai =
10866                             AppGlobals.getPackageManager().
10867                                 getApplicationInfo(
10868                                         cpi.applicationInfo.packageName,
10869                                         STOCK_PM_FLAGS, userId);
10870                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10871                         if (ai == null) {
10872                             Slog.w(TAG, "No package info for content provider "
10873                                     + cpi.name);
10874                             return null;
10875                         }
10876                         ai = getAppInfoForUser(ai, userId);
10877                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10878                     } catch (RemoteException ex) {
10879                         // pm is in same process, this will never happen.
10880                     } finally {
10881                         Binder.restoreCallingIdentity(ident);
10882                     }
10883                 }
10884
10885                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10886
10887                 if (r != null && cpr.canRunHere(r)) {
10888                     // If this is a multiprocess provider, then just return its
10889                     // info and allow the caller to instantiate it.  Only do
10890                     // this if the provider is the same user as the caller's
10891                     // process, or can run as root (so can be in any process).
10892                     return cpr.newHolder(null);
10893                 }
10894
10895                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10896                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10897                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10898
10899                 // This is single process, and our app is now connecting to it.
10900                 // See if we are already in the process of launching this
10901                 // provider.
10902                 final int N = mLaunchingProviders.size();
10903                 int i;
10904                 for (i = 0; i < N; i++) {
10905                     if (mLaunchingProviders.get(i) == cpr) {
10906                         break;
10907                     }
10908                 }
10909
10910                 // If the provider is not already being launched, then get it
10911                 // started.
10912                 if (i >= N) {
10913                     final long origId = Binder.clearCallingIdentity();
10914
10915                     try {
10916                         // Content provider is now in use, its package can't be stopped.
10917                         try {
10918                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10919                             AppGlobals.getPackageManager().setPackageStoppedState(
10920                                     cpr.appInfo.packageName, false, userId);
10921                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10922                         } catch (RemoteException e) {
10923                         } catch (IllegalArgumentException e) {
10924                             Slog.w(TAG, "Failed trying to unstop package "
10925                                     + cpr.appInfo.packageName + ": " + e);
10926                         }
10927
10928                         // Use existing process if already started
10929                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10930                         ProcessRecord proc = getProcessRecordLocked(
10931                                 cpi.processName, cpr.appInfo.uid, false);
10932                         if (proc != null && proc.thread != null && !proc.killed) {
10933                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10934                                     "Installing in existing process " + proc);
10935                             if (!proc.pubProviders.containsKey(cpi.name)) {
10936                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10937                                 proc.pubProviders.put(cpi.name, cpr);
10938                                 try {
10939                                     proc.thread.scheduleInstallProvider(cpi);
10940                                 } catch (RemoteException e) {
10941                                 }
10942                             }
10943                         } else {
10944                             checkTime(startTime, "getContentProviderImpl: before start process");
10945                             proc = startProcessLocked(cpi.processName,
10946                                     cpr.appInfo, false, 0, "content provider",
10947                                     new ComponentName(cpi.applicationInfo.packageName,
10948                                             cpi.name), false, false, false);
10949                             checkTime(startTime, "getContentProviderImpl: after start process");
10950                             if (proc == null) {
10951                                 Slog.w(TAG, "Unable to launch app "
10952                                         + cpi.applicationInfo.packageName + "/"
10953                                         + cpi.applicationInfo.uid + " for provider "
10954                                         + name + ": process is bad");
10955                                 return null;
10956                             }
10957                         }
10958                         cpr.launchingApp = proc;
10959                         mLaunchingProviders.add(cpr);
10960                     } finally {
10961                         Binder.restoreCallingIdentity(origId);
10962                     }
10963                 }
10964
10965                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10966
10967                 // Make sure the provider is published (the same provider class
10968                 // may be published under multiple names).
10969                 if (firstClass) {
10970                     mProviderMap.putProviderByClass(comp, cpr);
10971                 }
10972
10973                 mProviderMap.putProviderByName(name, cpr);
10974                 conn = incProviderCountLocked(r, cpr, token, stable);
10975                 if (conn != null) {
10976                     conn.waiting = true;
10977                 }
10978             }
10979             checkTime(startTime, "getContentProviderImpl: done!");
10980         }
10981
10982         // Wait for the provider to be published...
10983         synchronized (cpr) {
10984             while (cpr.provider == null) {
10985                 if (cpr.launchingApp == null) {
10986                     Slog.w(TAG, "Unable to launch app "
10987                             + cpi.applicationInfo.packageName + "/"
10988                             + cpi.applicationInfo.uid + " for provider "
10989                             + name + ": launching app became null");
10990                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10991                             UserHandle.getUserId(cpi.applicationInfo.uid),
10992                             cpi.applicationInfo.packageName,
10993                             cpi.applicationInfo.uid, name);
10994                     return null;
10995                 }
10996                 try {
10997                     if (DEBUG_MU) Slog.v(TAG_MU,
10998                             "Waiting to start provider " + cpr
10999                             + " launchingApp=" + cpr.launchingApp);
11000                     if (conn != null) {
11001                         conn.waiting = true;
11002                     }
11003                     cpr.wait();
11004                 } catch (InterruptedException ex) {
11005                 } finally {
11006                     if (conn != null) {
11007                         conn.waiting = false;
11008                     }
11009                 }
11010             }
11011         }
11012         return cpr != null ? cpr.newHolder(conn) : null;
11013     }
11014
11015     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11016             ProcessRecord r, final int userId) {
11017         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11018                 cpi.packageName, userId)) {
11019
11020             final boolean callerForeground = r == null || r.setSchedGroup
11021                     != ProcessList.SCHED_GROUP_BACKGROUND;
11022
11023             // Show a permission review UI only for starting from a foreground app
11024             if (!callerForeground) {
11025                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11026                         + cpi.packageName + " requires a permissions review");
11027                 return false;
11028             }
11029
11030             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11031             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11032                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11033             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11034
11035             if (DEBUG_PERMISSIONS_REVIEW) {
11036                 Slog.i(TAG, "u" + userId + " Launching permission review "
11037                         + "for package " + cpi.packageName);
11038             }
11039
11040             final UserHandle userHandle = new UserHandle(userId);
11041             mHandler.post(new Runnable() {
11042                 @Override
11043                 public void run() {
11044                     mContext.startActivityAsUser(intent, userHandle);
11045                 }
11046             });
11047
11048             return false;
11049         }
11050
11051         return true;
11052     }
11053
11054     PackageManagerInternal getPackageManagerInternalLocked() {
11055         if (mPackageManagerInt == null) {
11056             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11057         }
11058         return mPackageManagerInt;
11059     }
11060
11061     @Override
11062     public final ContentProviderHolder getContentProvider(
11063             IApplicationThread caller, String name, int userId, boolean stable) {
11064         enforceNotIsolatedCaller("getContentProvider");
11065         if (caller == null) {
11066             String msg = "null IApplicationThread when getting content provider "
11067                     + name;
11068             Slog.w(TAG, msg);
11069             throw new SecurityException(msg);
11070         }
11071         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11072         // with cross-user grant.
11073         return getContentProviderImpl(caller, name, null, stable, userId);
11074     }
11075
11076     public ContentProviderHolder getContentProviderExternal(
11077             String name, int userId, IBinder token) {
11078         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11079             "Do not have permission in call getContentProviderExternal()");
11080         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11081                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11082         return getContentProviderExternalUnchecked(name, token, userId);
11083     }
11084
11085     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11086             IBinder token, int userId) {
11087         return getContentProviderImpl(null, name, token, true, userId);
11088     }
11089
11090     /**
11091      * Drop a content provider from a ProcessRecord's bookkeeping
11092      */
11093     public void removeContentProvider(IBinder connection, boolean stable) {
11094         enforceNotIsolatedCaller("removeContentProvider");
11095         long ident = Binder.clearCallingIdentity();
11096         try {
11097             synchronized (this) {
11098                 ContentProviderConnection conn;
11099                 try {
11100                     conn = (ContentProviderConnection)connection;
11101                 } catch (ClassCastException e) {
11102                     String msg ="removeContentProvider: " + connection
11103                             + " not a ContentProviderConnection";
11104                     Slog.w(TAG, msg);
11105                     throw new IllegalArgumentException(msg);
11106                 }
11107                 if (conn == null) {
11108                     throw new NullPointerException("connection is null");
11109                 }
11110                 if (decProviderCountLocked(conn, null, null, stable)) {
11111                     updateOomAdjLocked();
11112                 }
11113             }
11114         } finally {
11115             Binder.restoreCallingIdentity(ident);
11116         }
11117     }
11118
11119     public void removeContentProviderExternal(String name, IBinder token) {
11120         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11121             "Do not have permission in call removeContentProviderExternal()");
11122         int userId = UserHandle.getCallingUserId();
11123         long ident = Binder.clearCallingIdentity();
11124         try {
11125             removeContentProviderExternalUnchecked(name, token, userId);
11126         } finally {
11127             Binder.restoreCallingIdentity(ident);
11128         }
11129     }
11130
11131     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11132         synchronized (this) {
11133             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11134             if(cpr == null) {
11135                 //remove from mProvidersByClass
11136                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11137                 return;
11138             }
11139
11140             //update content provider record entry info
11141             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11142             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11143             if (localCpr.hasExternalProcessHandles()) {
11144                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11145                     updateOomAdjLocked();
11146                 } else {
11147                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11148                             + " with no external reference for token: "
11149                             + token + ".");
11150                 }
11151             } else {
11152                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11153                         + " with no external references.");
11154             }
11155         }
11156     }
11157
11158     public final void publishContentProviders(IApplicationThread caller,
11159             List<ContentProviderHolder> providers) {
11160         if (providers == null) {
11161             return;
11162         }
11163
11164         enforceNotIsolatedCaller("publishContentProviders");
11165         synchronized (this) {
11166             final ProcessRecord r = getRecordForAppLocked(caller);
11167             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11168             if (r == null) {
11169                 throw new SecurityException(
11170                         "Unable to find app for caller " + caller
11171                       + " (pid=" + Binder.getCallingPid()
11172                       + ") when publishing content providers");
11173             }
11174
11175             final long origId = Binder.clearCallingIdentity();
11176
11177             final int N = providers.size();
11178             for (int i = 0; i < N; i++) {
11179                 ContentProviderHolder src = providers.get(i);
11180                 if (src == null || src.info == null || src.provider == null) {
11181                     continue;
11182                 }
11183                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11184                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11185                 if (dst != null) {
11186                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11187                     mProviderMap.putProviderByClass(comp, dst);
11188                     String names[] = dst.info.authority.split(";");
11189                     for (int j = 0; j < names.length; j++) {
11190                         mProviderMap.putProviderByName(names[j], dst);
11191                     }
11192
11193                     int launchingCount = mLaunchingProviders.size();
11194                     int j;
11195                     boolean wasInLaunchingProviders = false;
11196                     for (j = 0; j < launchingCount; j++) {
11197                         if (mLaunchingProviders.get(j) == dst) {
11198                             mLaunchingProviders.remove(j);
11199                             wasInLaunchingProviders = true;
11200                             j--;
11201                             launchingCount--;
11202                         }
11203                     }
11204                     if (wasInLaunchingProviders) {
11205                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11206                     }
11207                     synchronized (dst) {
11208                         dst.provider = src.provider;
11209                         dst.proc = r;
11210                         dst.notifyAll();
11211                     }
11212                     updateOomAdjLocked(r);
11213                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11214                             src.info.authority);
11215                 }
11216             }
11217
11218             Binder.restoreCallingIdentity(origId);
11219         }
11220     }
11221
11222     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11223         ContentProviderConnection conn;
11224         try {
11225             conn = (ContentProviderConnection)connection;
11226         } catch (ClassCastException e) {
11227             String msg ="refContentProvider: " + connection
11228                     + " not a ContentProviderConnection";
11229             Slog.w(TAG, msg);
11230             throw new IllegalArgumentException(msg);
11231         }
11232         if (conn == null) {
11233             throw new NullPointerException("connection is null");
11234         }
11235
11236         synchronized (this) {
11237             if (stable > 0) {
11238                 conn.numStableIncs += stable;
11239             }
11240             stable = conn.stableCount + stable;
11241             if (stable < 0) {
11242                 throw new IllegalStateException("stableCount < 0: " + stable);
11243             }
11244
11245             if (unstable > 0) {
11246                 conn.numUnstableIncs += unstable;
11247             }
11248             unstable = conn.unstableCount + unstable;
11249             if (unstable < 0) {
11250                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11251             }
11252
11253             if ((stable+unstable) <= 0) {
11254                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11255                         + stable + " unstable=" + unstable);
11256             }
11257             conn.stableCount = stable;
11258             conn.unstableCount = unstable;
11259             return !conn.dead;
11260         }
11261     }
11262
11263     public void unstableProviderDied(IBinder connection) {
11264         ContentProviderConnection conn;
11265         try {
11266             conn = (ContentProviderConnection)connection;
11267         } catch (ClassCastException e) {
11268             String msg ="refContentProvider: " + connection
11269                     + " not a ContentProviderConnection";
11270             Slog.w(TAG, msg);
11271             throw new IllegalArgumentException(msg);
11272         }
11273         if (conn == null) {
11274             throw new NullPointerException("connection is null");
11275         }
11276
11277         // Safely retrieve the content provider associated with the connection.
11278         IContentProvider provider;
11279         synchronized (this) {
11280             provider = conn.provider.provider;
11281         }
11282
11283         if (provider == null) {
11284             // Um, yeah, we're way ahead of you.
11285             return;
11286         }
11287
11288         // Make sure the caller is being honest with us.
11289         if (provider.asBinder().pingBinder()) {
11290             // Er, no, still looks good to us.
11291             synchronized (this) {
11292                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11293                         + " says " + conn + " died, but we don't agree");
11294                 return;
11295             }
11296         }
11297
11298         // Well look at that!  It's dead!
11299         synchronized (this) {
11300             if (conn.provider.provider != provider) {
11301                 // But something changed...  good enough.
11302                 return;
11303             }
11304
11305             ProcessRecord proc = conn.provider.proc;
11306             if (proc == null || proc.thread == null) {
11307                 // Seems like the process is already cleaned up.
11308                 return;
11309             }
11310
11311             // As far as we're concerned, this is just like receiving a
11312             // death notification...  just a bit prematurely.
11313             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11314                     + ") early provider death");
11315             final long ident = Binder.clearCallingIdentity();
11316             try {
11317                 appDiedLocked(proc);
11318             } finally {
11319                 Binder.restoreCallingIdentity(ident);
11320             }
11321         }
11322     }
11323
11324     @Override
11325     public void appNotRespondingViaProvider(IBinder connection) {
11326         enforceCallingPermission(
11327                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11328
11329         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11330         if (conn == null) {
11331             Slog.w(TAG, "ContentProviderConnection is null");
11332             return;
11333         }
11334
11335         final ProcessRecord host = conn.provider.proc;
11336         if (host == null) {
11337             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11338             return;
11339         }
11340
11341         mHandler.post(new Runnable() {
11342             @Override
11343             public void run() {
11344                 mAppErrors.appNotResponding(host, null, null, false,
11345                         "ContentProvider not responding");
11346             }
11347         });
11348     }
11349
11350     public final void installSystemProviders() {
11351         List<ProviderInfo> providers;
11352         synchronized (this) {
11353             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11354             providers = generateApplicationProvidersLocked(app);
11355             if (providers != null) {
11356                 for (int i=providers.size()-1; i>=0; i--) {
11357                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11358                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11359                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11360                                 + ": not system .apk");
11361                         providers.remove(i);
11362                     }
11363                 }
11364             }
11365         }
11366         if (providers != null) {
11367             mSystemThread.installSystemProviders(providers);
11368         }
11369
11370         mCoreSettingsObserver = new CoreSettingsObserver(this);
11371         mFontScaleSettingObserver = new FontScaleSettingObserver();
11372
11373         //mUsageStatsService.monitorPackages();
11374     }
11375
11376     private void startPersistentApps(int matchFlags) {
11377         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11378
11379         synchronized (this) {
11380             try {
11381                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11382                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11383                 for (ApplicationInfo app : apps) {
11384                     if (!"android".equals(app.packageName)) {
11385                         addAppLocked(app, false, null /* ABI override */);
11386                     }
11387                 }
11388             } catch (RemoteException ex) {
11389             }
11390         }
11391     }
11392
11393     /**
11394      * When a user is unlocked, we need to install encryption-unaware providers
11395      * belonging to any running apps.
11396      */
11397     private void installEncryptionUnawareProviders(int userId) {
11398         // We're only interested in providers that are encryption unaware, and
11399         // we don't care about uninstalled apps, since there's no way they're
11400         // running at this point.
11401         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11402
11403         synchronized (this) {
11404             final int NP = mProcessNames.getMap().size();
11405             for (int ip = 0; ip < NP; ip++) {
11406                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11407                 final int NA = apps.size();
11408                 for (int ia = 0; ia < NA; ia++) {
11409                     final ProcessRecord app = apps.valueAt(ia);
11410                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11411
11412                     final int NG = app.pkgList.size();
11413                     for (int ig = 0; ig < NG; ig++) {
11414                         try {
11415                             final String pkgName = app.pkgList.keyAt(ig);
11416                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11417                                     .getPackageInfo(pkgName, matchFlags, userId);
11418                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11419                                 for (ProviderInfo pi : pkgInfo.providers) {
11420                                     // TODO: keep in sync with generateApplicationProvidersLocked
11421                                     final boolean processMatch = Objects.equals(pi.processName,
11422                                             app.processName) || pi.multiprocess;
11423                                     final boolean userMatch = isSingleton(pi.processName,
11424                                             pi.applicationInfo, pi.name, pi.flags)
11425                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11426                                     if (processMatch && userMatch) {
11427                                         Log.v(TAG, "Installing " + pi);
11428                                         app.thread.scheduleInstallProvider(pi);
11429                                     } else {
11430                                         Log.v(TAG, "Skipping " + pi);
11431                                     }
11432                                 }
11433                             }
11434                         } catch (RemoteException ignored) {
11435                         }
11436                     }
11437                 }
11438             }
11439         }
11440     }
11441
11442     /**
11443      * Allows apps to retrieve the MIME type of a URI.
11444      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11445      * users, then it does not need permission to access the ContentProvider.
11446      * Either, it needs cross-user uri grants.
11447      *
11448      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11449      *
11450      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11451      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11452      */
11453     public String getProviderMimeType(Uri uri, int userId) {
11454         enforceNotIsolatedCaller("getProviderMimeType");
11455         final String name = uri.getAuthority();
11456         int callingUid = Binder.getCallingUid();
11457         int callingPid = Binder.getCallingPid();
11458         long ident = 0;
11459         boolean clearedIdentity = false;
11460         synchronized (this) {
11461             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11462         }
11463         if (canClearIdentity(callingPid, callingUid, userId)) {
11464             clearedIdentity = true;
11465             ident = Binder.clearCallingIdentity();
11466         }
11467         ContentProviderHolder holder = null;
11468         try {
11469             holder = getContentProviderExternalUnchecked(name, null, userId);
11470             if (holder != null) {
11471                 return holder.provider.getType(uri);
11472             }
11473         } catch (RemoteException e) {
11474             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11475             return null;
11476         } catch (Exception e) {
11477             Log.w(TAG, "Exception while determining type of " + uri, e);
11478             return null;
11479         } finally {
11480             // We need to clear the identity to call removeContentProviderExternalUnchecked
11481             if (!clearedIdentity) {
11482                 ident = Binder.clearCallingIdentity();
11483             }
11484             try {
11485                 if (holder != null) {
11486                     removeContentProviderExternalUnchecked(name, null, userId);
11487                 }
11488             } finally {
11489                 Binder.restoreCallingIdentity(ident);
11490             }
11491         }
11492
11493         return null;
11494     }
11495
11496     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11497         if (UserHandle.getUserId(callingUid) == userId) {
11498             return true;
11499         }
11500         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11501                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11502                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11503                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11504                 return true;
11505         }
11506         return false;
11507     }
11508
11509     // =========================================================
11510     // GLOBAL MANAGEMENT
11511     // =========================================================
11512
11513     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11514             boolean isolated, int isolatedUid) {
11515         String proc = customProcess != null ? customProcess : info.processName;
11516         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11517         final int userId = UserHandle.getUserId(info.uid);
11518         int uid = info.uid;
11519         if (isolated) {
11520             if (isolatedUid == 0) {
11521                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11522                 while (true) {
11523                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11524                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11525                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11526                     }
11527                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11528                     mNextIsolatedProcessUid++;
11529                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11530                         // No process for this uid, use it.
11531                         break;
11532                     }
11533                     stepsLeft--;
11534                     if (stepsLeft <= 0) {
11535                         return null;
11536                     }
11537                 }
11538             } else {
11539                 // Special case for startIsolatedProcess (internal only), where
11540                 // the uid of the isolated process is specified by the caller.
11541                 uid = isolatedUid;
11542             }
11543
11544             // Register the isolated UID with this application so BatteryStats knows to
11545             // attribute resource usage to the application.
11546             //
11547             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11548             // about the process state of the isolated UID *before* it is registered with the
11549             // owning application.
11550             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11551         }
11552         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11553         if (!mBooted && !mBooting
11554                 && userId == UserHandle.USER_SYSTEM
11555                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11556             r.persistent = true;
11557         }
11558         addProcessNameLocked(r);
11559         return r;
11560     }
11561
11562     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11563             String abiOverride) {
11564         ProcessRecord app;
11565         if (!isolated) {
11566             app = getProcessRecordLocked(info.processName, info.uid, true);
11567         } else {
11568             app = null;
11569         }
11570
11571         if (app == null) {
11572             app = newProcessRecordLocked(info, null, isolated, 0);
11573             updateLruProcessLocked(app, false, null);
11574             updateOomAdjLocked();
11575         }
11576
11577         // This package really, really can not be stopped.
11578         try {
11579             AppGlobals.getPackageManager().setPackageStoppedState(
11580                     info.packageName, false, UserHandle.getUserId(app.uid));
11581         } catch (RemoteException e) {
11582         } catch (IllegalArgumentException e) {
11583             Slog.w(TAG, "Failed trying to unstop package "
11584                     + info.packageName + ": " + e);
11585         }
11586
11587         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11588             app.persistent = true;
11589             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11590         }
11591         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11592             mPersistentStartingProcesses.add(app);
11593             startProcessLocked(app, "added application", app.processName, abiOverride,
11594                     null /* entryPoint */, null /* entryPointArgs */);
11595         }
11596
11597         return app;
11598     }
11599
11600     public void unhandledBack() {
11601         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11602                 "unhandledBack()");
11603
11604         synchronized(this) {
11605             final long origId = Binder.clearCallingIdentity();
11606             try {
11607                 getFocusedStack().unhandledBackLocked();
11608             } finally {
11609                 Binder.restoreCallingIdentity(origId);
11610             }
11611         }
11612     }
11613
11614     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11615         enforceNotIsolatedCaller("openContentUri");
11616         final int userId = UserHandle.getCallingUserId();
11617         String name = uri.getAuthority();
11618         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11619         ParcelFileDescriptor pfd = null;
11620         if (cph != null) {
11621             // We record the binder invoker's uid in thread-local storage before
11622             // going to the content provider to open the file.  Later, in the code
11623             // that handles all permissions checks, we look for this uid and use
11624             // that rather than the Activity Manager's own uid.  The effect is that
11625             // we do the check against the caller's permissions even though it looks
11626             // to the content provider like the Activity Manager itself is making
11627             // the request.
11628             Binder token = new Binder();
11629             sCallerIdentity.set(new Identity(
11630                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11631             try {
11632                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11633             } catch (FileNotFoundException e) {
11634                 // do nothing; pfd will be returned null
11635             } finally {
11636                 // Ensure that whatever happens, we clean up the identity state
11637                 sCallerIdentity.remove();
11638                 // Ensure we're done with the provider.
11639                 removeContentProviderExternalUnchecked(name, null, userId);
11640             }
11641         } else {
11642             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11643         }
11644         return pfd;
11645     }
11646
11647     // Actually is sleeping or shutting down or whatever else in the future
11648     // is an inactive state.
11649     boolean isSleepingOrShuttingDownLocked() {
11650         return isSleepingLocked() || mShuttingDown;
11651     }
11652
11653     boolean isShuttingDownLocked() {
11654         return mShuttingDown;
11655     }
11656
11657     boolean isSleepingLocked() {
11658         return mSleeping;
11659     }
11660
11661     void onWakefulnessChanged(int wakefulness) {
11662         synchronized(this) {
11663             mWakefulness = wakefulness;
11664             updateSleepIfNeededLocked();
11665         }
11666     }
11667
11668     void finishRunningVoiceLocked() {
11669         if (mRunningVoice != null) {
11670             mRunningVoice = null;
11671             mVoiceWakeLock.release();
11672             updateSleepIfNeededLocked();
11673         }
11674     }
11675
11676     void startTimeTrackingFocusedActivityLocked() {
11677         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11678             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11679         }
11680     }
11681
11682     void updateSleepIfNeededLocked() {
11683         if (mSleeping && !shouldSleepLocked()) {
11684             mSleeping = false;
11685             startTimeTrackingFocusedActivityLocked();
11686             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11687             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11688             updateOomAdjLocked();
11689         } else if (!mSleeping && shouldSleepLocked()) {
11690             mSleeping = true;
11691             if (mCurAppTimeTracker != null) {
11692                 mCurAppTimeTracker.stop();
11693             }
11694             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11695             mStackSupervisor.goingToSleepLocked();
11696             updateOomAdjLocked();
11697
11698             // Initialize the wake times of all processes.
11699             checkExcessivePowerUsageLocked(false);
11700             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11701             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11702             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11703         }
11704     }
11705
11706     private boolean shouldSleepLocked() {
11707         // Resume applications while running a voice interactor.
11708         if (mRunningVoice != null) {
11709             return false;
11710         }
11711
11712         // TODO: Transform the lock screen state into a sleep token instead.
11713         switch (mWakefulness) {
11714             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11715             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11716             case PowerManagerInternal.WAKEFULNESS_DOZING:
11717                 // Pause applications whenever the lock screen is shown or any sleep
11718                 // tokens have been acquired.
11719                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11720             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11721             default:
11722                 // If we're asleep then pause applications unconditionally.
11723                 return true;
11724         }
11725     }
11726
11727     /** Pokes the task persister. */
11728     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11729         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11730     }
11731
11732     /** Notifies all listeners when the task stack has changed. */
11733     void notifyTaskStackChangedLocked() {
11734         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11735         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11736         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11737         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11738     }
11739
11740     /** Notifies all listeners when an Activity is pinned. */
11741     void notifyActivityPinnedLocked() {
11742         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11743         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11744     }
11745
11746     /**
11747      * Notifies all listeners when an attempt was made to start an an activity that is already
11748      * running in the pinned stack and the activity was not actually started, but the task is
11749      * either brought to the front or a new Intent is delivered to it.
11750      */
11751     void notifyPinnedActivityRestartAttemptLocked() {
11752         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11753         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11754     }
11755
11756     /** Notifies all listeners when the pinned stack animation ends. */
11757     @Override
11758     public void notifyPinnedStackAnimationEnded() {
11759         synchronized (this) {
11760             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11761             mHandler.obtainMessage(
11762                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11763         }
11764     }
11765
11766     @Override
11767     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11768         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11769     }
11770
11771     @Override
11772     public boolean shutdown(int timeout) {
11773         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11774                 != PackageManager.PERMISSION_GRANTED) {
11775             throw new SecurityException("Requires permission "
11776                     + android.Manifest.permission.SHUTDOWN);
11777         }
11778
11779         boolean timedout = false;
11780
11781         synchronized(this) {
11782             mShuttingDown = true;
11783             updateEventDispatchingLocked();
11784             timedout = mStackSupervisor.shutdownLocked(timeout);
11785         }
11786
11787         mAppOpsService.shutdown();
11788         if (mUsageStatsService != null) {
11789             mUsageStatsService.prepareShutdown();
11790         }
11791         mBatteryStatsService.shutdown();
11792         synchronized (this) {
11793             mProcessStats.shutdownLocked();
11794             notifyTaskPersisterLocked(null, true);
11795         }
11796
11797         return timedout;
11798     }
11799
11800     public final void activitySlept(IBinder token) {
11801         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11802
11803         final long origId = Binder.clearCallingIdentity();
11804
11805         synchronized (this) {
11806             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11807             if (r != null) {
11808                 mStackSupervisor.activitySleptLocked(r);
11809             }
11810         }
11811
11812         Binder.restoreCallingIdentity(origId);
11813     }
11814
11815     private String lockScreenShownToString() {
11816         switch (mLockScreenShown) {
11817             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11818             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11819             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11820             default: return "Unknown=" + mLockScreenShown;
11821         }
11822     }
11823
11824     void logLockScreen(String msg) {
11825         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11826                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11827                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11828                 + " mSleeping=" + mSleeping);
11829     }
11830
11831     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11832         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11833         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11834         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11835             boolean wasRunningVoice = mRunningVoice != null;
11836             mRunningVoice = session;
11837             if (!wasRunningVoice) {
11838                 mVoiceWakeLock.acquire();
11839                 updateSleepIfNeededLocked();
11840             }
11841         }
11842     }
11843
11844     private void updateEventDispatchingLocked() {
11845         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11846     }
11847
11848     public void setLockScreenShown(boolean showing, boolean occluded) {
11849         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11850                 != PackageManager.PERMISSION_GRANTED) {
11851             throw new SecurityException("Requires permission "
11852                     + android.Manifest.permission.DEVICE_POWER);
11853         }
11854
11855         synchronized(this) {
11856             long ident = Binder.clearCallingIdentity();
11857             try {
11858                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11859                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11860                 if (showing && occluded) {
11861                     // The lock screen is currently showing, but is occluded by a window that can
11862                     // show on top of the lock screen. In this can we want to dismiss the docked
11863                     // stack since it will be complicated/risky to try to put the activity on top
11864                     // of the lock screen in the right fullscreen configuration.
11865                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11866                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11867                 }
11868
11869                 updateSleepIfNeededLocked();
11870             } finally {
11871                 Binder.restoreCallingIdentity(ident);
11872             }
11873         }
11874     }
11875
11876     @Override
11877     public void notifyLockedProfile(@UserIdInt int userId) {
11878         try {
11879             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11880                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11881             }
11882         } catch (RemoteException ex) {
11883             throw new SecurityException("Fail to check is caller a privileged app", ex);
11884         }
11885
11886         synchronized (this) {
11887             if (mStackSupervisor.isUserLockedProfile(userId)) {
11888                 final long ident = Binder.clearCallingIdentity();
11889                 try {
11890                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11891
11892                     // Drop locked freeform tasks out into the fullscreen stack.
11893                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11894                     //       where they were before, but in an obscured state.
11895                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11896
11897                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11898                         // If there is no device lock, we will show the profile's credential page.
11899                         mActivityStarter.showConfirmDeviceCredential(userId);
11900                     } else {
11901                         // Showing launcher to avoid user entering credential twice.
11902                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11903                     }
11904                 } finally {
11905                     Binder.restoreCallingIdentity(ident);
11906                 }
11907             }
11908         }
11909     }
11910
11911     @Override
11912     public void startConfirmDeviceCredentialIntent(Intent intent) {
11913         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11914         synchronized (this) {
11915             final long ident = Binder.clearCallingIdentity();
11916             try {
11917                 mActivityStarter.startConfirmCredentialIntent(intent);
11918             } finally {
11919                 Binder.restoreCallingIdentity(ident);
11920             }
11921         }
11922     }
11923
11924     @Override
11925     public void stopAppSwitches() {
11926         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11927                 != PackageManager.PERMISSION_GRANTED) {
11928             throw new SecurityException("viewquires permission "
11929                     + android.Manifest.permission.STOP_APP_SWITCHES);
11930         }
11931
11932         synchronized(this) {
11933             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11934                     + APP_SWITCH_DELAY_TIME;
11935             mDidAppSwitch = false;
11936             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11937             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11938             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11939         }
11940     }
11941
11942     public void resumeAppSwitches() {
11943         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11944                 != PackageManager.PERMISSION_GRANTED) {
11945             throw new SecurityException("Requires permission "
11946                     + android.Manifest.permission.STOP_APP_SWITCHES);
11947         }
11948
11949         synchronized(this) {
11950             // Note that we don't execute any pending app switches... we will
11951             // let those wait until either the timeout, or the next start
11952             // activity request.
11953             mAppSwitchesAllowedTime = 0;
11954         }
11955     }
11956
11957     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11958             int callingPid, int callingUid, String name) {
11959         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11960             return true;
11961         }
11962
11963         int perm = checkComponentPermission(
11964                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11965                 sourceUid, -1, true);
11966         if (perm == PackageManager.PERMISSION_GRANTED) {
11967             return true;
11968         }
11969
11970         // If the actual IPC caller is different from the logical source, then
11971         // also see if they are allowed to control app switches.
11972         if (callingUid != -1 && callingUid != sourceUid) {
11973             perm = checkComponentPermission(
11974                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11975                     callingUid, -1, true);
11976             if (perm == PackageManager.PERMISSION_GRANTED) {
11977                 return true;
11978             }
11979         }
11980
11981         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11982         return false;
11983     }
11984
11985     public void setDebugApp(String packageName, boolean waitForDebugger,
11986             boolean persistent) {
11987         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11988                 "setDebugApp()");
11989
11990         long ident = Binder.clearCallingIdentity();
11991         try {
11992             // Note that this is not really thread safe if there are multiple
11993             // callers into it at the same time, but that's not a situation we
11994             // care about.
11995             if (persistent) {
11996                 final ContentResolver resolver = mContext.getContentResolver();
11997                 Settings.Global.putString(
11998                     resolver, Settings.Global.DEBUG_APP,
11999                     packageName);
12000                 Settings.Global.putInt(
12001                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12002                     waitForDebugger ? 1 : 0);
12003             }
12004
12005             synchronized (this) {
12006                 if (!persistent) {
12007                     mOrigDebugApp = mDebugApp;
12008                     mOrigWaitForDebugger = mWaitForDebugger;
12009                 }
12010                 mDebugApp = packageName;
12011                 mWaitForDebugger = waitForDebugger;
12012                 mDebugTransient = !persistent;
12013                 if (packageName != null) {
12014                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12015                             false, UserHandle.USER_ALL, "set debug app");
12016                 }
12017             }
12018         } finally {
12019             Binder.restoreCallingIdentity(ident);
12020         }
12021     }
12022
12023     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12024         synchronized (this) {
12025             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12026             if (!isDebuggable) {
12027                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12028                     throw new SecurityException("Process not debuggable: " + app.packageName);
12029                 }
12030             }
12031
12032             mTrackAllocationApp = processName;
12033         }
12034     }
12035
12036     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12037         synchronized (this) {
12038             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12039             if (!isDebuggable) {
12040                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12041                     throw new SecurityException("Process not debuggable: " + app.packageName);
12042                 }
12043             }
12044             mProfileApp = processName;
12045             mProfileFile = profilerInfo.profileFile;
12046             if (mProfileFd != null) {
12047                 try {
12048                     mProfileFd.close();
12049                 } catch (IOException e) {
12050                 }
12051                 mProfileFd = null;
12052             }
12053             mProfileFd = profilerInfo.profileFd;
12054             mSamplingInterval = profilerInfo.samplingInterval;
12055             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12056             mProfileType = 0;
12057         }
12058     }
12059
12060     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12061         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12062         if (!isDebuggable) {
12063             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12064                 throw new SecurityException("Process not debuggable: " + app.packageName);
12065             }
12066         }
12067         mNativeDebuggingApp = processName;
12068     }
12069
12070     @Override
12071     public void setAlwaysFinish(boolean enabled) {
12072         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12073                 "setAlwaysFinish()");
12074
12075         long ident = Binder.clearCallingIdentity();
12076         try {
12077             Settings.Global.putInt(
12078                     mContext.getContentResolver(),
12079                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12080
12081             synchronized (this) {
12082                 mAlwaysFinishActivities = enabled;
12083             }
12084         } finally {
12085             Binder.restoreCallingIdentity(ident);
12086         }
12087     }
12088
12089     @Override
12090     public void setLenientBackgroundCheck(boolean enabled) {
12091         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12092                 "setLenientBackgroundCheck()");
12093
12094         long ident = Binder.clearCallingIdentity();
12095         try {
12096             Settings.Global.putInt(
12097                     mContext.getContentResolver(),
12098                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12099
12100             synchronized (this) {
12101                 mLenientBackgroundCheck = enabled;
12102             }
12103         } finally {
12104             Binder.restoreCallingIdentity(ident);
12105         }
12106     }
12107
12108     @Override
12109     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12110         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12111                 "setActivityController()");
12112         synchronized (this) {
12113             mController = controller;
12114             mControllerIsAMonkey = imAMonkey;
12115             Watchdog.getInstance().setActivityController(controller);
12116         }
12117     }
12118
12119     @Override
12120     public void setUserIsMonkey(boolean userIsMonkey) {
12121         synchronized (this) {
12122             synchronized (mPidsSelfLocked) {
12123                 final int callingPid = Binder.getCallingPid();
12124                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12125                 if (precessRecord == null) {
12126                     throw new SecurityException("Unknown process: " + callingPid);
12127                 }
12128                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12129                     throw new SecurityException("Only an instrumentation process "
12130                             + "with a UiAutomation can call setUserIsMonkey");
12131                 }
12132             }
12133             mUserIsMonkey = userIsMonkey;
12134         }
12135     }
12136
12137     @Override
12138     public boolean isUserAMonkey() {
12139         synchronized (this) {
12140             // If there is a controller also implies the user is a monkey.
12141             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12142         }
12143     }
12144
12145     public void requestBugReport(int bugreportType) {
12146         String service = null;
12147         switch (bugreportType) {
12148             case ActivityManager.BUGREPORT_OPTION_FULL:
12149                 service = "bugreport";
12150                 break;
12151             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12152                 service = "bugreportplus";
12153                 break;
12154             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12155                 service = "bugreportremote";
12156                 break;
12157             case ActivityManager.BUGREPORT_OPTION_WEAR:
12158                 service = "bugreportwear";
12159                 break;
12160         }
12161         if (service == null) {
12162             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12163                     + bugreportType);
12164         }
12165         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12166         SystemProperties.set("ctl.start", service);
12167     }
12168
12169     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12170         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12171     }
12172
12173     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12174         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12175             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12176         }
12177         return KEY_DISPATCHING_TIMEOUT;
12178     }
12179
12180     @Override
12181     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12182         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12183                 != PackageManager.PERMISSION_GRANTED) {
12184             throw new SecurityException("Requires permission "
12185                     + android.Manifest.permission.FILTER_EVENTS);
12186         }
12187         ProcessRecord proc;
12188         long timeout;
12189         synchronized (this) {
12190             synchronized (mPidsSelfLocked) {
12191                 proc = mPidsSelfLocked.get(pid);
12192             }
12193             timeout = getInputDispatchingTimeoutLocked(proc);
12194         }
12195
12196         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12197             return -1;
12198         }
12199
12200         return timeout;
12201     }
12202
12203     /**
12204      * Handle input dispatching timeouts.
12205      * Returns whether input dispatching should be aborted or not.
12206      */
12207     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12208             final ActivityRecord activity, final ActivityRecord parent,
12209             final boolean aboveSystem, String reason) {
12210         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12211                 != PackageManager.PERMISSION_GRANTED) {
12212             throw new SecurityException("Requires permission "
12213                     + android.Manifest.permission.FILTER_EVENTS);
12214         }
12215
12216         final String annotation;
12217         if (reason == null) {
12218             annotation = "Input dispatching timed out";
12219         } else {
12220             annotation = "Input dispatching timed out (" + reason + ")";
12221         }
12222
12223         if (proc != null) {
12224             synchronized (this) {
12225                 if (proc.debugging) {
12226                     return false;
12227                 }
12228
12229                 if (mDidDexOpt) {
12230                     // Give more time since we were dexopting.
12231                     mDidDexOpt = false;
12232                     return false;
12233                 }
12234
12235                 if (proc.instrumentationClass != null) {
12236                     Bundle info = new Bundle();
12237                     info.putString("shortMsg", "keyDispatchingTimedOut");
12238                     info.putString("longMsg", annotation);
12239                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12240                     return true;
12241                 }
12242             }
12243             mHandler.post(new Runnable() {
12244                 @Override
12245                 public void run() {
12246                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12247                 }
12248             });
12249         }
12250
12251         return true;
12252     }
12253
12254     @Override
12255     public Bundle getAssistContextExtras(int requestType) {
12256         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12257                 null, null, true /* focused */, true /* newSessionId */,
12258                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12259         if (pae == null) {
12260             return null;
12261         }
12262         synchronized (pae) {
12263             while (!pae.haveResult) {
12264                 try {
12265                     pae.wait();
12266                 } catch (InterruptedException e) {
12267                 }
12268             }
12269         }
12270         synchronized (this) {
12271             buildAssistBundleLocked(pae, pae.result);
12272             mPendingAssistExtras.remove(pae);
12273             mUiHandler.removeCallbacks(pae);
12274         }
12275         return pae.extras;
12276     }
12277
12278     @Override
12279     public boolean isAssistDataAllowedOnCurrentActivity() {
12280         int userId;
12281         synchronized (this) {
12282             userId = mUserController.getCurrentUserIdLocked();
12283             ActivityRecord activity = getFocusedStack().topActivity();
12284             if (activity == null) {
12285                 return false;
12286             }
12287             userId = activity.userId;
12288         }
12289         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12290                 Context.DEVICE_POLICY_SERVICE);
12291         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12292     }
12293
12294     @Override
12295     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12296         long ident = Binder.clearCallingIdentity();
12297         try {
12298             synchronized (this) {
12299                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12300                 ActivityRecord top = getFocusedStack().topActivity();
12301                 if (top != caller) {
12302                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12303                             + " is not current top " + top);
12304                     return false;
12305                 }
12306                 if (!top.nowVisible) {
12307                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12308                             + " is not visible");
12309                     return false;
12310                 }
12311             }
12312             AssistUtils utils = new AssistUtils(mContext);
12313             return utils.showSessionForActiveService(args,
12314                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12315         } finally {
12316             Binder.restoreCallingIdentity(ident);
12317         }
12318     }
12319
12320     @Override
12321     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12322             Bundle receiverExtras,
12323             IBinder activityToken, boolean focused, boolean newSessionId) {
12324         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12325                 activityToken, focused, newSessionId,
12326                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12327                 != null;
12328     }
12329
12330     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12331             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12332             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12333         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12334                 "enqueueAssistContext()");
12335         synchronized (this) {
12336             ActivityRecord activity = getFocusedStack().topActivity();
12337             if (activity == null) {
12338                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12339                 return null;
12340             }
12341             if (activity.app == null || activity.app.thread == null) {
12342                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12343                 return null;
12344             }
12345             if (focused) {
12346                 if (activityToken != null) {
12347                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12348                     if (activity != caller) {
12349                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12350                                 + " is not current top " + activity);
12351                         return null;
12352                     }
12353                 }
12354             } else {
12355                 activity = ActivityRecord.forTokenLocked(activityToken);
12356                 if (activity == null) {
12357                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12358                             + " couldn't be found");
12359                     return null;
12360                 }
12361             }
12362
12363             PendingAssistExtras pae;
12364             Bundle extras = new Bundle();
12365             if (args != null) {
12366                 extras.putAll(args);
12367             }
12368             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12369             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12370             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12371                     userHandle);
12372             // Increment the sessionId if necessary
12373             if (newSessionId) {
12374                 mViSessionId++;
12375             }
12376             try {
12377                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12378                         requestType, mViSessionId);
12379                 mPendingAssistExtras.add(pae);
12380                 mUiHandler.postDelayed(pae, timeout);
12381             } catch (RemoteException e) {
12382                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12383                 return null;
12384             }
12385             return pae;
12386         }
12387     }
12388
12389     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12390         IResultReceiver receiver;
12391         synchronized (this) {
12392             mPendingAssistExtras.remove(pae);
12393             receiver = pae.receiver;
12394         }
12395         if (receiver != null) {
12396             // Caller wants result sent back to them.
12397             Bundle sendBundle = new Bundle();
12398             // At least return the receiver extras
12399             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12400                     pae.receiverExtras);
12401             try {
12402                 pae.receiver.send(0, sendBundle);
12403             } catch (RemoteException e) {
12404             }
12405         }
12406     }
12407
12408     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12409         if (result != null) {
12410             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12411         }
12412         if (pae.hint != null) {
12413             pae.extras.putBoolean(pae.hint, true);
12414         }
12415     }
12416
12417     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12418             AssistContent content, Uri referrer) {
12419         PendingAssistExtras pae = (PendingAssistExtras)token;
12420         synchronized (pae) {
12421             pae.result = extras;
12422             pae.structure = structure;
12423             pae.content = content;
12424             if (referrer != null) {
12425                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12426             }
12427             pae.haveResult = true;
12428             pae.notifyAll();
12429             if (pae.intent == null && pae.receiver == null) {
12430                 // Caller is just waiting for the result.
12431                 return;
12432             }
12433         }
12434
12435         // We are now ready to launch the assist activity.
12436         IResultReceiver sendReceiver = null;
12437         Bundle sendBundle = null;
12438         synchronized (this) {
12439             buildAssistBundleLocked(pae, extras);
12440             boolean exists = mPendingAssistExtras.remove(pae);
12441             mUiHandler.removeCallbacks(pae);
12442             if (!exists) {
12443                 // Timed out.
12444                 return;
12445             }
12446             if ((sendReceiver=pae.receiver) != null) {
12447                 // Caller wants result sent back to them.
12448                 sendBundle = new Bundle();
12449                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12450                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12451                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12452                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12453                         pae.receiverExtras);
12454             }
12455         }
12456         if (sendReceiver != null) {
12457             try {
12458                 sendReceiver.send(0, sendBundle);
12459             } catch (RemoteException e) {
12460             }
12461             return;
12462         }
12463
12464         long ident = Binder.clearCallingIdentity();
12465         try {
12466             pae.intent.replaceExtras(pae.extras);
12467             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12468                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12469                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12470             closeSystemDialogs("assist");
12471             try {
12472                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12473             } catch (ActivityNotFoundException e) {
12474                 Slog.w(TAG, "No activity to handle assist action.", e);
12475             }
12476         } finally {
12477             Binder.restoreCallingIdentity(ident);
12478         }
12479     }
12480
12481     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12482             Bundle args) {
12483         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12484                 true /* focused */, true /* newSessionId */,
12485                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12486     }
12487
12488     public void registerProcessObserver(IProcessObserver observer) {
12489         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12490                 "registerProcessObserver()");
12491         synchronized (this) {
12492             mProcessObservers.register(observer);
12493         }
12494     }
12495
12496     @Override
12497     public void unregisterProcessObserver(IProcessObserver observer) {
12498         synchronized (this) {
12499             mProcessObservers.unregister(observer);
12500         }
12501     }
12502
12503     @Override
12504     public void registerUidObserver(IUidObserver observer, int which) {
12505         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12506                 "registerUidObserver()");
12507         synchronized (this) {
12508             mUidObservers.register(observer, which);
12509         }
12510     }
12511
12512     @Override
12513     public void unregisterUidObserver(IUidObserver observer) {
12514         synchronized (this) {
12515             mUidObservers.unregister(observer);
12516         }
12517     }
12518
12519     @Override
12520     public boolean convertFromTranslucent(IBinder token) {
12521         final long origId = Binder.clearCallingIdentity();
12522         try {
12523             synchronized (this) {
12524                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12525                 if (r == null) {
12526                     return false;
12527                 }
12528                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12529                 if (translucentChanged) {
12530                     r.task.stack.releaseBackgroundResources(r);
12531                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12532                 }
12533                 mWindowManager.setAppFullscreen(token, true);
12534                 return translucentChanged;
12535             }
12536         } finally {
12537             Binder.restoreCallingIdentity(origId);
12538         }
12539     }
12540
12541     @Override
12542     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12543         final long origId = Binder.clearCallingIdentity();
12544         try {
12545             synchronized (this) {
12546                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12547                 if (r == null) {
12548                     return false;
12549                 }
12550                 int index = r.task.mActivities.lastIndexOf(r);
12551                 if (index > 0) {
12552                     ActivityRecord under = r.task.mActivities.get(index - 1);
12553                     under.returningOptions = options;
12554                 }
12555                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12556                 if (translucentChanged) {
12557                     r.task.stack.convertActivityToTranslucent(r);
12558                 }
12559                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12560                 mWindowManager.setAppFullscreen(token, false);
12561                 return translucentChanged;
12562             }
12563         } finally {
12564             Binder.restoreCallingIdentity(origId);
12565         }
12566     }
12567
12568     @Override
12569     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12570         final long origId = Binder.clearCallingIdentity();
12571         try {
12572             synchronized (this) {
12573                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12574                 if (r != null) {
12575                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12576                 }
12577             }
12578             return false;
12579         } finally {
12580             Binder.restoreCallingIdentity(origId);
12581         }
12582     }
12583
12584     @Override
12585     public boolean isBackgroundVisibleBehind(IBinder token) {
12586         final long origId = Binder.clearCallingIdentity();
12587         try {
12588             synchronized (this) {
12589                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12590                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12591                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12592                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12593                 return visible;
12594             }
12595         } finally {
12596             Binder.restoreCallingIdentity(origId);
12597         }
12598     }
12599
12600     @Override
12601     public ActivityOptions getActivityOptions(IBinder token) {
12602         final long origId = Binder.clearCallingIdentity();
12603         try {
12604             synchronized (this) {
12605                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12606                 if (r != null) {
12607                     final ActivityOptions activityOptions = r.pendingOptions;
12608                     r.pendingOptions = null;
12609                     return activityOptions;
12610                 }
12611                 return null;
12612             }
12613         } finally {
12614             Binder.restoreCallingIdentity(origId);
12615         }
12616     }
12617
12618     @Override
12619     public void setImmersive(IBinder token, boolean immersive) {
12620         synchronized(this) {
12621             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12622             if (r == null) {
12623                 throw new IllegalArgumentException();
12624             }
12625             r.immersive = immersive;
12626
12627             // update associated state if we're frontmost
12628             if (r == mFocusedActivity) {
12629                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12630                 applyUpdateLockStateLocked(r);
12631             }
12632         }
12633     }
12634
12635     @Override
12636     public boolean isImmersive(IBinder token) {
12637         synchronized (this) {
12638             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12639             if (r == null) {
12640                 throw new IllegalArgumentException();
12641             }
12642             return r.immersive;
12643         }
12644     }
12645
12646     public void setVrThread(int tid) {
12647         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12648             throw new UnsupportedOperationException("VR mode not supported on this device!");
12649         }
12650
12651         synchronized (this) {
12652             ProcessRecord proc;
12653             synchronized (mPidsSelfLocked) {
12654                 final int pid = Binder.getCallingPid();
12655                 proc = mPidsSelfLocked.get(pid);
12656
12657                 if (proc != null && mInVrMode && tid >= 0) {
12658                     // ensure the tid belongs to the process
12659                     if (!Process.isThreadInProcess(pid, tid)) {
12660                         throw new IllegalArgumentException("VR thread does not belong to process");
12661                     }
12662
12663                     // reset existing VR thread to CFS if this thread still exists and belongs to
12664                     // the calling process
12665                     if (proc.vrThreadTid != 0
12666                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12667                         try {
12668                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12669                         } catch (IllegalArgumentException e) {
12670                             // Ignore this.  Only occurs in race condition where previous VR thread
12671                             // was destroyed during this method call.
12672                         }
12673                     }
12674
12675                     proc.vrThreadTid = tid;
12676
12677                     // promote to FIFO now if the tid is non-zero
12678                     try {
12679                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12680                             proc.vrThreadTid > 0) {
12681                             Process.setThreadScheduler(proc.vrThreadTid,
12682                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12683                         }
12684                     } catch (IllegalArgumentException e) {
12685                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12686                                + " not exist:\n" + e);
12687                     }
12688                 }
12689             }
12690         }
12691     }
12692
12693     @Override
12694     public void setRenderThread(int tid) {
12695         synchronized (this) {
12696             ProcessRecord proc;
12697             synchronized (mPidsSelfLocked) {
12698                 int pid = Binder.getCallingPid();
12699                 proc = mPidsSelfLocked.get(pid);
12700                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12701                     // ensure the tid belongs to the process
12702                     if (!Process.isThreadInProcess(pid, tid)) {
12703                         throw new IllegalArgumentException(
12704                             "Render thread does not belong to process");
12705                     }
12706                     proc.renderThreadTid = tid;
12707                     if (DEBUG_OOM_ADJ) {
12708                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12709                     }
12710                     // promote to FIFO now
12711                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12712                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12713                         if (mUseFifoUiScheduling) {
12714                             Process.setThreadScheduler(proc.renderThreadTid,
12715                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12716                         } else {
12717                             Process.setThreadPriority(proc.renderThreadTid, -10);
12718                         }
12719                     }
12720                 } else {
12721                     if (DEBUG_OOM_ADJ) {
12722                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12723                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12724                                mUseFifoUiScheduling);
12725                     }
12726                 }
12727             }
12728         }
12729     }
12730
12731     @Override
12732     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12733         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12734             throw new UnsupportedOperationException("VR mode not supported on this device!");
12735         }
12736
12737         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12738
12739         ActivityRecord r;
12740         synchronized (this) {
12741             r = ActivityRecord.isInStackLocked(token);
12742         }
12743
12744         if (r == null) {
12745             throw new IllegalArgumentException();
12746         }
12747
12748         int err;
12749         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12750                 VrManagerInternal.NO_ERROR) {
12751             return err;
12752         }
12753
12754         synchronized(this) {
12755             r.requestedVrComponent = (enabled) ? packageName : null;
12756
12757             // Update associated state if this activity is currently focused
12758             if (r == mFocusedActivity) {
12759                 applyUpdateVrModeLocked(r);
12760             }
12761             return 0;
12762         }
12763     }
12764
12765     @Override
12766     public boolean isVrModePackageEnabled(ComponentName packageName) {
12767         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12768             throw new UnsupportedOperationException("VR mode not supported on this device!");
12769         }
12770
12771         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12772
12773         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12774                 VrManagerInternal.NO_ERROR;
12775     }
12776
12777     public boolean isTopActivityImmersive() {
12778         enforceNotIsolatedCaller("startActivity");
12779         synchronized (this) {
12780             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12781             return (r != null) ? r.immersive : false;
12782         }
12783     }
12784
12785     @Override
12786     public boolean isTopOfTask(IBinder token) {
12787         synchronized (this) {
12788             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12789             if (r == null) {
12790                 throw new IllegalArgumentException();
12791             }
12792             return r.task.getTopActivity() == r;
12793         }
12794     }
12795
12796     @Override
12797     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12798         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12799             String msg = "Permission Denial: setHasTopUi() from pid="
12800                     + Binder.getCallingPid()
12801                     + ", uid=" + Binder.getCallingUid()
12802                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12803             Slog.w(TAG, msg);
12804             throw new SecurityException(msg);
12805         }
12806         final int pid = Binder.getCallingPid();
12807         final long origId = Binder.clearCallingIdentity();
12808         try {
12809             synchronized (this) {
12810                 boolean changed = false;
12811                 ProcessRecord pr;
12812                 synchronized (mPidsSelfLocked) {
12813                     pr = mPidsSelfLocked.get(pid);
12814                     if (pr == null) {
12815                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12816                         return;
12817                     }
12818                     if (pr.hasTopUi != hasTopUi) {
12819                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12820                         pr.hasTopUi = hasTopUi;
12821                         changed = true;
12822                     }
12823                 }
12824                 if (changed) {
12825                     updateOomAdjLocked(pr);
12826                 }
12827             }
12828         } finally {
12829             Binder.restoreCallingIdentity(origId);
12830         }
12831     }
12832
12833     public final void enterSafeMode() {
12834         synchronized(this) {
12835             // It only makes sense to do this before the system is ready
12836             // and started launching other packages.
12837             if (!mSystemReady) {
12838                 try {
12839                     AppGlobals.getPackageManager().enterSafeMode();
12840                 } catch (RemoteException e) {
12841                 }
12842             }
12843
12844             mSafeMode = true;
12845         }
12846     }
12847
12848     public final void showSafeModeOverlay() {
12849         View v = LayoutInflater.from(mContext).inflate(
12850                 com.android.internal.R.layout.safe_mode, null);
12851         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12852         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12853         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12854         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12855         lp.gravity = Gravity.BOTTOM | Gravity.START;
12856         lp.format = v.getBackground().getOpacity();
12857         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12858                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12859         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12860         ((WindowManager)mContext.getSystemService(
12861                 Context.WINDOW_SERVICE)).addView(v, lp);
12862     }
12863
12864     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12865         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12866             return;
12867         }
12868         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12869         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12870         synchronized (stats) {
12871             if (mBatteryStatsService.isOnBattery()) {
12872                 mBatteryStatsService.enforceCallingPermission();
12873                 int MY_UID = Binder.getCallingUid();
12874                 final int uid;
12875                 if (sender == null) {
12876                     uid = sourceUid;
12877                 } else {
12878                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12879                 }
12880                 BatteryStatsImpl.Uid.Pkg pkg =
12881                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12882                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12883                 pkg.noteWakeupAlarmLocked(tag);
12884             }
12885         }
12886     }
12887
12888     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12889         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12890             return;
12891         }
12892         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12893         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12894         synchronized (stats) {
12895             mBatteryStatsService.enforceCallingPermission();
12896             int MY_UID = Binder.getCallingUid();
12897             final int uid;
12898             if (sender == null) {
12899                 uid = sourceUid;
12900             } else {
12901                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12902             }
12903             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12904         }
12905     }
12906
12907     public void noteAlarmFinish(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.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12923         }
12924     }
12925
12926     public boolean killPids(int[] pids, String pReason, boolean secure) {
12927         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12928             throw new SecurityException("killPids only available to the system");
12929         }
12930         String reason = (pReason == null) ? "Unknown" : pReason;
12931         // XXX Note: don't acquire main activity lock here, because the window
12932         // manager calls in with its locks held.
12933
12934         boolean killed = false;
12935         synchronized (mPidsSelfLocked) {
12936             int worstType = 0;
12937             for (int i=0; i<pids.length; i++) {
12938                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12939                 if (proc != null) {
12940                     int type = proc.setAdj;
12941                     if (type > worstType) {
12942                         worstType = type;
12943                     }
12944                 }
12945             }
12946
12947             // If the worst oom_adj is somewhere in the cached proc LRU range,
12948             // then constrain it so we will kill all cached procs.
12949             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12950                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12951                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12952             }
12953
12954             // If this is not a secure call, don't let it kill processes that
12955             // are important.
12956             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12957                 worstType = ProcessList.SERVICE_ADJ;
12958             }
12959
12960             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12961             for (int i=0; i<pids.length; i++) {
12962                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12963                 if (proc == null) {
12964                     continue;
12965                 }
12966                 int adj = proc.setAdj;
12967                 if (adj >= worstType && !proc.killedByAm) {
12968                     proc.kill(reason, true);
12969                     killed = true;
12970                 }
12971             }
12972         }
12973         return killed;
12974     }
12975
12976     @Override
12977     public void killUid(int appId, int userId, String reason) {
12978         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12979         synchronized (this) {
12980             final long identity = Binder.clearCallingIdentity();
12981             try {
12982                 killPackageProcessesLocked(null, appId, userId,
12983                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12984                         reason != null ? reason : "kill uid");
12985             } finally {
12986                 Binder.restoreCallingIdentity(identity);
12987             }
12988         }
12989     }
12990
12991     @Override
12992     public boolean killProcessesBelowForeground(String reason) {
12993         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12994             throw new SecurityException("killProcessesBelowForeground() only available to system");
12995         }
12996
12997         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12998     }
12999
13000     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13001         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13002             throw new SecurityException("killProcessesBelowAdj() only available to system");
13003         }
13004
13005         boolean killed = false;
13006         synchronized (mPidsSelfLocked) {
13007             final int size = mPidsSelfLocked.size();
13008             for (int i = 0; i < size; i++) {
13009                 final int pid = mPidsSelfLocked.keyAt(i);
13010                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13011                 if (proc == null) continue;
13012
13013                 final int adj = proc.setAdj;
13014                 if (adj > belowAdj && !proc.killedByAm) {
13015                     proc.kill(reason, true);
13016                     killed = true;
13017                 }
13018             }
13019         }
13020         return killed;
13021     }
13022
13023     @Override
13024     public void hang(final IBinder who, boolean allowRestart) {
13025         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13026                 != PackageManager.PERMISSION_GRANTED) {
13027             throw new SecurityException("Requires permission "
13028                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13029         }
13030
13031         final IBinder.DeathRecipient death = new DeathRecipient() {
13032             @Override
13033             public void binderDied() {
13034                 synchronized (this) {
13035                     notifyAll();
13036                 }
13037             }
13038         };
13039
13040         try {
13041             who.linkToDeath(death, 0);
13042         } catch (RemoteException e) {
13043             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13044             return;
13045         }
13046
13047         synchronized (this) {
13048             Watchdog.getInstance().setAllowRestart(allowRestart);
13049             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13050             synchronized (death) {
13051                 while (who.isBinderAlive()) {
13052                     try {
13053                         death.wait();
13054                     } catch (InterruptedException e) {
13055                     }
13056                 }
13057             }
13058             Watchdog.getInstance().setAllowRestart(true);
13059         }
13060     }
13061
13062     @Override
13063     public void restart() {
13064         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13065                 != PackageManager.PERMISSION_GRANTED) {
13066             throw new SecurityException("Requires permission "
13067                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13068         }
13069
13070         Log.i(TAG, "Sending shutdown broadcast...");
13071
13072         BroadcastReceiver br = new BroadcastReceiver() {
13073             @Override public void onReceive(Context context, Intent intent) {
13074                 // Now the broadcast is done, finish up the low-level shutdown.
13075                 Log.i(TAG, "Shutting down activity manager...");
13076                 shutdown(10000);
13077                 Log.i(TAG, "Shutdown complete, restarting!");
13078                 Process.killProcess(Process.myPid());
13079                 System.exit(10);
13080             }
13081         };
13082
13083         // First send the high-level shut down broadcast.
13084         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13085         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13086         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13087         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13088         mContext.sendOrderedBroadcastAsUser(intent,
13089                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13090         */
13091         br.onReceive(mContext, intent);
13092     }
13093
13094     private long getLowRamTimeSinceIdle(long now) {
13095         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13096     }
13097
13098     @Override
13099     public void performIdleMaintenance() {
13100         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13101                 != PackageManager.PERMISSION_GRANTED) {
13102             throw new SecurityException("Requires permission "
13103                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13104         }
13105
13106         synchronized (this) {
13107             final long now = SystemClock.uptimeMillis();
13108             final long timeSinceLastIdle = now - mLastIdleTime;
13109             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13110             mLastIdleTime = now;
13111             mLowRamTimeSinceLastIdle = 0;
13112             if (mLowRamStartTime != 0) {
13113                 mLowRamStartTime = now;
13114             }
13115
13116             StringBuilder sb = new StringBuilder(128);
13117             sb.append("Idle maintenance over ");
13118             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13119             sb.append(" low RAM for ");
13120             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13121             Slog.i(TAG, sb.toString());
13122
13123             // If at least 1/3 of our time since the last idle period has been spent
13124             // with RAM low, then we want to kill processes.
13125             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13126
13127             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13128                 ProcessRecord proc = mLruProcesses.get(i);
13129                 if (proc.notCachedSinceIdle) {
13130                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13131                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13132                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13133                         if (doKilling && proc.initialIdlePss != 0
13134                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13135                             sb = new StringBuilder(128);
13136                             sb.append("Kill");
13137                             sb.append(proc.processName);
13138                             sb.append(" in idle maint: pss=");
13139                             sb.append(proc.lastPss);
13140                             sb.append(", swapPss=");
13141                             sb.append(proc.lastSwapPss);
13142                             sb.append(", initialPss=");
13143                             sb.append(proc.initialIdlePss);
13144                             sb.append(", period=");
13145                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13146                             sb.append(", lowRamPeriod=");
13147                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13148                             Slog.wtfQuiet(TAG, sb.toString());
13149                             proc.kill("idle maint (pss " + proc.lastPss
13150                                     + " from " + proc.initialIdlePss + ")", true);
13151                         }
13152                     }
13153                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13154                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13155                     proc.notCachedSinceIdle = true;
13156                     proc.initialIdlePss = 0;
13157                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13158                             mTestPssMode, isSleepingLocked(), now);
13159                 }
13160             }
13161
13162             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13163             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13164         }
13165     }
13166
13167     @Override
13168     public void sendIdleJobTrigger() {
13169         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13170                 != PackageManager.PERMISSION_GRANTED) {
13171             throw new SecurityException("Requires permission "
13172                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13173         }
13174
13175         final long ident = Binder.clearCallingIdentity();
13176         try {
13177             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13178                     .setPackage("android")
13179                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13180             broadcastIntent(null, intent, null, null, 0, null, null, null,
13181                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13182         } finally {
13183             Binder.restoreCallingIdentity(ident);
13184         }
13185     }
13186
13187     private void retrieveSettings() {
13188         final ContentResolver resolver = mContext.getContentResolver();
13189         final boolean freeformWindowManagement =
13190                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13191                         || Settings.Global.getInt(
13192                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13193         final boolean supportsPictureInPicture =
13194                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13195
13196         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13197         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13198         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13199         final boolean alwaysFinishActivities =
13200                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13201         final boolean lenientBackgroundCheck =
13202                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13203         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13204         final boolean forceResizable = Settings.Global.getInt(
13205                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13206         final boolean supportsLeanbackOnly =
13207                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13208
13209         // Transfer any global setting for forcing RTL layout, into a System Property
13210         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13211
13212         final Configuration configuration = new Configuration();
13213         Settings.System.getConfiguration(resolver, configuration);
13214         if (forceRtl) {
13215             // This will take care of setting the correct layout direction flags
13216             configuration.setLayoutDirection(configuration.locale);
13217         }
13218
13219         synchronized (this) {
13220             mDebugApp = mOrigDebugApp = debugApp;
13221             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13222             mAlwaysFinishActivities = alwaysFinishActivities;
13223             mLenientBackgroundCheck = lenientBackgroundCheck;
13224             mSupportsLeanbackOnly = supportsLeanbackOnly;
13225             mForceResizableActivities = forceResizable;
13226             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13227             if (supportsMultiWindow || forceResizable) {
13228                 mSupportsMultiWindow = true;
13229                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13230                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13231             } else {
13232                 mSupportsMultiWindow = false;
13233                 mSupportsFreeformWindowManagement = false;
13234                 mSupportsPictureInPicture = false;
13235             }
13236             // This happens before any activities are started, so we can
13237             // change mConfiguration in-place.
13238             updateConfigurationLocked(configuration, null, true);
13239             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13240                     "Initial config: " + mConfiguration);
13241
13242             // Load resources only after the current configuration has been set.
13243             final Resources res = mContext.getResources();
13244             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13245             mThumbnailWidth = res.getDimensionPixelSize(
13246                     com.android.internal.R.dimen.thumbnail_width);
13247             mThumbnailHeight = res.getDimensionPixelSize(
13248                     com.android.internal.R.dimen.thumbnail_height);
13249             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13250                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13251             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13252                     com.android.internal.R.string.config_appsNotReportingCrashes));
13253             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13254                 mFullscreenThumbnailScale = (float) res
13255                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13256                     (float) mConfiguration.screenWidthDp;
13257             } else {
13258                 mFullscreenThumbnailScale = res.getFraction(
13259                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13260             }
13261         }
13262     }
13263
13264     public boolean testIsSystemReady() {
13265         // no need to synchronize(this) just to read & return the value
13266         return mSystemReady;
13267     }
13268
13269     public void systemReady(final Runnable goingCallback) {
13270         synchronized(this) {
13271             if (mSystemReady) {
13272                 // If we're done calling all the receivers, run the next "boot phase" passed in
13273                 // by the SystemServer
13274                 if (goingCallback != null) {
13275                     goingCallback.run();
13276                 }
13277                 return;
13278             }
13279
13280             mLocalDeviceIdleController
13281                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13282
13283             // Make sure we have the current profile info, since it is needed for security checks.
13284             mUserController.onSystemReady();
13285             mRecentTasks.onSystemReadyLocked();
13286             mAppOpsService.systemReady();
13287             mSystemReady = true;
13288         }
13289
13290         ArrayList<ProcessRecord> procsToKill = null;
13291         synchronized(mPidsSelfLocked) {
13292             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13293                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13294                 if (!isAllowedWhileBooting(proc.info)){
13295                     if (procsToKill == null) {
13296                         procsToKill = new ArrayList<ProcessRecord>();
13297                     }
13298                     procsToKill.add(proc);
13299                 }
13300             }
13301         }
13302
13303         synchronized(this) {
13304             if (procsToKill != null) {
13305                 for (int i=procsToKill.size()-1; i>=0; i--) {
13306                     ProcessRecord proc = procsToKill.get(i);
13307                     Slog.i(TAG, "Removing system update proc: " + proc);
13308                     removeProcessLocked(proc, true, false, "system update done");
13309                 }
13310             }
13311
13312             // Now that we have cleaned up any update processes, we
13313             // are ready to start launching real processes and know that
13314             // we won't trample on them any more.
13315             mProcessesReady = true;
13316         }
13317
13318         Slog.i(TAG, "System now ready");
13319         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13320             SystemClock.uptimeMillis());
13321
13322         synchronized(this) {
13323             // Make sure we have no pre-ready processes sitting around.
13324
13325             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13326                 ResolveInfo ri = mContext.getPackageManager()
13327                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13328                                 STOCK_PM_FLAGS);
13329                 CharSequence errorMsg = null;
13330                 if (ri != null) {
13331                     ActivityInfo ai = ri.activityInfo;
13332                     ApplicationInfo app = ai.applicationInfo;
13333                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13334                         mTopAction = Intent.ACTION_FACTORY_TEST;
13335                         mTopData = null;
13336                         mTopComponent = new ComponentName(app.packageName,
13337                                 ai.name);
13338                     } else {
13339                         errorMsg = mContext.getResources().getText(
13340                                 com.android.internal.R.string.factorytest_not_system);
13341                     }
13342                 } else {
13343                     errorMsg = mContext.getResources().getText(
13344                             com.android.internal.R.string.factorytest_no_action);
13345                 }
13346                 if (errorMsg != null) {
13347                     mTopAction = null;
13348                     mTopData = null;
13349                     mTopComponent = null;
13350                     Message msg = Message.obtain();
13351                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13352                     msg.getData().putCharSequence("msg", errorMsg);
13353                     mUiHandler.sendMessage(msg);
13354                 }
13355             }
13356         }
13357
13358         retrieveSettings();
13359         final int currentUserId;
13360         synchronized (this) {
13361             currentUserId = mUserController.getCurrentUserIdLocked();
13362             readGrantedUriPermissionsLocked();
13363         }
13364
13365         if (goingCallback != null) goingCallback.run();
13366
13367         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13368                 Integer.toString(currentUserId), currentUserId);
13369         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13370                 Integer.toString(currentUserId), currentUserId);
13371         mSystemServiceManager.startUser(currentUserId);
13372
13373         synchronized (this) {
13374             // Only start up encryption-aware persistent apps; once user is
13375             // unlocked we'll come back around and start unaware apps
13376             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13377
13378             // Start up initial activity.
13379             mBooting = true;
13380             // Enable home activity for system user, so that the system can always boot
13381             if (UserManager.isSplitSystemUser()) {
13382                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13383                 try {
13384                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13385                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13386                             UserHandle.USER_SYSTEM);
13387                 } catch (RemoteException e) {
13388                     throw e.rethrowAsRuntimeException();
13389                 }
13390             }
13391             startHomeActivityLocked(currentUserId, "systemReady");
13392
13393             try {
13394                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13395                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13396                             + " data partition or your device will be unstable.");
13397                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13398                 }
13399             } catch (RemoteException e) {
13400             }
13401
13402             if (!Build.isBuildConsistent()) {
13403                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13404                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13405             }
13406
13407             long ident = Binder.clearCallingIdentity();
13408             try {
13409                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13410                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13411                         | Intent.FLAG_RECEIVER_FOREGROUND);
13412                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13413                 broadcastIntentLocked(null, null, intent,
13414                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13415                         null, false, false, MY_PID, Process.SYSTEM_UID,
13416                         currentUserId);
13417                 intent = new Intent(Intent.ACTION_USER_STARTING);
13418                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13419                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13420                 broadcastIntentLocked(null, null, intent,
13421                         null, new IIntentReceiver.Stub() {
13422                             @Override
13423                             public void performReceive(Intent intent, int resultCode, String data,
13424                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13425                                     throws RemoteException {
13426                             }
13427                         }, 0, null, null,
13428                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13429                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13430             } catch (Throwable t) {
13431                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13432             } finally {
13433                 Binder.restoreCallingIdentity(ident);
13434             }
13435             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13436             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13437         }
13438     }
13439
13440     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13441         synchronized (this) {
13442             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13443         }
13444     }
13445
13446     void skipCurrentReceiverLocked(ProcessRecord app) {
13447         for (BroadcastQueue queue : mBroadcastQueues) {
13448             queue.skipCurrentReceiverLocked(app);
13449         }
13450     }
13451
13452     /**
13453      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13454      * The application process will exit immediately after this call returns.
13455      * @param app object of the crashing app, null for the system server
13456      * @param crashInfo describing the exception
13457      */
13458     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13459         ProcessRecord r = findAppProcess(app, "Crash");
13460         final String processName = app == null ? "system_server"
13461                 : (r == null ? "unknown" : r.processName);
13462
13463         handleApplicationCrashInner("crash", r, processName, crashInfo);
13464     }
13465
13466     /* Native crash reporting uses this inner version because it needs to be somewhat
13467      * decoupled from the AM-managed cleanup lifecycle
13468      */
13469     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13470             ApplicationErrorReport.CrashInfo crashInfo) {
13471         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13472                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13473                 r == null ? -1 : r.info.flags,
13474                 crashInfo.exceptionClassName,
13475                 crashInfo.exceptionMessage,
13476                 crashInfo.throwFileName,
13477                 crashInfo.throwLineNumber);
13478
13479         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13480
13481         mAppErrors.crashApplication(r, crashInfo);
13482     }
13483
13484     public void handleApplicationStrictModeViolation(
13485             IBinder app,
13486             int violationMask,
13487             StrictMode.ViolationInfo info) {
13488         ProcessRecord r = findAppProcess(app, "StrictMode");
13489         if (r == null) {
13490             return;
13491         }
13492
13493         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13494             Integer stackFingerprint = info.hashCode();
13495             boolean logIt = true;
13496             synchronized (mAlreadyLoggedViolatedStacks) {
13497                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13498                     logIt = false;
13499                     // TODO: sub-sample into EventLog for these, with
13500                     // the info.durationMillis?  Then we'd get
13501                     // the relative pain numbers, without logging all
13502                     // the stack traces repeatedly.  We'd want to do
13503                     // likewise in the client code, which also does
13504                     // dup suppression, before the Binder call.
13505                 } else {
13506                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13507                         mAlreadyLoggedViolatedStacks.clear();
13508                     }
13509                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13510                 }
13511             }
13512             if (logIt) {
13513                 logStrictModeViolationToDropBox(r, info);
13514             }
13515         }
13516
13517         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13518             AppErrorResult result = new AppErrorResult();
13519             synchronized (this) {
13520                 final long origId = Binder.clearCallingIdentity();
13521
13522                 Message msg = Message.obtain();
13523                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13524                 HashMap<String, Object> data = new HashMap<String, Object>();
13525                 data.put("result", result);
13526                 data.put("app", r);
13527                 data.put("violationMask", violationMask);
13528                 data.put("info", info);
13529                 msg.obj = data;
13530                 mUiHandler.sendMessage(msg);
13531
13532                 Binder.restoreCallingIdentity(origId);
13533             }
13534             int res = result.get();
13535             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13536         }
13537     }
13538
13539     // Depending on the policy in effect, there could be a bunch of
13540     // these in quick succession so we try to batch these together to
13541     // minimize disk writes, number of dropbox entries, and maximize
13542     // compression, by having more fewer, larger records.
13543     private void logStrictModeViolationToDropBox(
13544             ProcessRecord process,
13545             StrictMode.ViolationInfo info) {
13546         if (info == null) {
13547             return;
13548         }
13549         final boolean isSystemApp = process == null ||
13550                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13551                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13552         final String processName = process == null ? "unknown" : process.processName;
13553         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13554         final DropBoxManager dbox = (DropBoxManager)
13555                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13556
13557         // Exit early if the dropbox isn't configured to accept this report type.
13558         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13559
13560         boolean bufferWasEmpty;
13561         boolean needsFlush;
13562         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13563         synchronized (sb) {
13564             bufferWasEmpty = sb.length() == 0;
13565             appendDropBoxProcessHeaders(process, processName, sb);
13566             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13567             sb.append("System-App: ").append(isSystemApp).append("\n");
13568             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13569             if (info.violationNumThisLoop != 0) {
13570                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13571             }
13572             if (info.numAnimationsRunning != 0) {
13573                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13574             }
13575             if (info.broadcastIntentAction != null) {
13576                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13577             }
13578             if (info.durationMillis != -1) {
13579                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13580             }
13581             if (info.numInstances != -1) {
13582                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13583             }
13584             if (info.tags != null) {
13585                 for (String tag : info.tags) {
13586                     sb.append("Span-Tag: ").append(tag).append("\n");
13587                 }
13588             }
13589             sb.append("\n");
13590             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13591                 sb.append(info.crashInfo.stackTrace);
13592                 sb.append("\n");
13593             }
13594             if (info.message != null) {
13595                 sb.append(info.message);
13596                 sb.append("\n");
13597             }
13598
13599             // Only buffer up to ~64k.  Various logging bits truncate
13600             // things at 128k.
13601             needsFlush = (sb.length() > 64 * 1024);
13602         }
13603
13604         // Flush immediately if the buffer's grown too large, or this
13605         // is a non-system app.  Non-system apps are isolated with a
13606         // different tag & policy and not batched.
13607         //
13608         // Batching is useful during internal testing with
13609         // StrictMode settings turned up high.  Without batching,
13610         // thousands of separate files could be created on boot.
13611         if (!isSystemApp || needsFlush) {
13612             new Thread("Error dump: " + dropboxTag) {
13613                 @Override
13614                 public void run() {
13615                     String report;
13616                     synchronized (sb) {
13617                         report = sb.toString();
13618                         sb.delete(0, sb.length());
13619                         sb.trimToSize();
13620                     }
13621                     if (report.length() != 0) {
13622                         dbox.addText(dropboxTag, report);
13623                     }
13624                 }
13625             }.start();
13626             return;
13627         }
13628
13629         // System app batching:
13630         if (!bufferWasEmpty) {
13631             // An existing dropbox-writing thread is outstanding, so
13632             // we don't need to start it up.  The existing thread will
13633             // catch the buffer appends we just did.
13634             return;
13635         }
13636
13637         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13638         // (After this point, we shouldn't access AMS internal data structures.)
13639         new Thread("Error dump: " + dropboxTag) {
13640             @Override
13641             public void run() {
13642                 // 5 second sleep to let stacks arrive and be batched together
13643                 try {
13644                     Thread.sleep(5000);  // 5 seconds
13645                 } catch (InterruptedException e) {}
13646
13647                 String errorReport;
13648                 synchronized (mStrictModeBuffer) {
13649                     errorReport = mStrictModeBuffer.toString();
13650                     if (errorReport.length() == 0) {
13651                         return;
13652                     }
13653                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13654                     mStrictModeBuffer.trimToSize();
13655                 }
13656                 dbox.addText(dropboxTag, errorReport);
13657             }
13658         }.start();
13659     }
13660
13661     /**
13662      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13663      * @param app object of the crashing app, null for the system server
13664      * @param tag reported by the caller
13665      * @param system whether this wtf is coming from the system
13666      * @param crashInfo describing the context of the error
13667      * @return true if the process should exit immediately (WTF is fatal)
13668      */
13669     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13670             final ApplicationErrorReport.CrashInfo crashInfo) {
13671         final int callingUid = Binder.getCallingUid();
13672         final int callingPid = Binder.getCallingPid();
13673
13674         if (system) {
13675             // If this is coming from the system, we could very well have low-level
13676             // system locks held, so we want to do this all asynchronously.  And we
13677             // never want this to become fatal, so there is that too.
13678             mHandler.post(new Runnable() {
13679                 @Override public void run() {
13680                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13681                 }
13682             });
13683             return false;
13684         }
13685
13686         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13687                 crashInfo);
13688
13689         if (r != null && r.pid != Process.myPid() &&
13690                 Settings.Global.getInt(mContext.getContentResolver(),
13691                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13692             mAppErrors.crashApplication(r, crashInfo);
13693             return true;
13694         } else {
13695             return false;
13696         }
13697     }
13698
13699     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13700             final ApplicationErrorReport.CrashInfo crashInfo) {
13701         final ProcessRecord r = findAppProcess(app, "WTF");
13702         final String processName = app == null ? "system_server"
13703                 : (r == null ? "unknown" : r.processName);
13704
13705         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13706                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13707
13708         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13709
13710         return r;
13711     }
13712
13713     /**
13714      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13715      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13716      */
13717     private ProcessRecord findAppProcess(IBinder app, String reason) {
13718         if (app == null) {
13719             return null;
13720         }
13721
13722         synchronized (this) {
13723             final int NP = mProcessNames.getMap().size();
13724             for (int ip=0; ip<NP; ip++) {
13725                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13726                 final int NA = apps.size();
13727                 for (int ia=0; ia<NA; ia++) {
13728                     ProcessRecord p = apps.valueAt(ia);
13729                     if (p.thread != null && p.thread.asBinder() == app) {
13730                         return p;
13731                     }
13732                 }
13733             }
13734
13735             Slog.w(TAG, "Can't find mystery application for " + reason
13736                     + " from pid=" + Binder.getCallingPid()
13737                     + " uid=" + Binder.getCallingUid() + ": " + app);
13738             return null;
13739         }
13740     }
13741
13742     /**
13743      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13744      * to append various headers to the dropbox log text.
13745      */
13746     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13747             StringBuilder sb) {
13748         // Watchdog thread ends up invoking this function (with
13749         // a null ProcessRecord) to add the stack file to dropbox.
13750         // Do not acquire a lock on this (am) in such cases, as it
13751         // could cause a potential deadlock, if and when watchdog
13752         // is invoked due to unavailability of lock on am and it
13753         // would prevent watchdog from killing system_server.
13754         if (process == null) {
13755             sb.append("Process: ").append(processName).append("\n");
13756             return;
13757         }
13758         // Note: ProcessRecord 'process' is guarded by the service
13759         // instance.  (notably process.pkgList, which could otherwise change
13760         // concurrently during execution of this method)
13761         synchronized (this) {
13762             sb.append("Process: ").append(processName).append("\n");
13763             int flags = process.info.flags;
13764             IPackageManager pm = AppGlobals.getPackageManager();
13765             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13766             for (int ip=0; ip<process.pkgList.size(); ip++) {
13767                 String pkg = process.pkgList.keyAt(ip);
13768                 sb.append("Package: ").append(pkg);
13769                 try {
13770                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13771                     if (pi != null) {
13772                         sb.append(" v").append(pi.versionCode);
13773                         if (pi.versionName != null) {
13774                             sb.append(" (").append(pi.versionName).append(")");
13775                         }
13776                     }
13777                 } catch (RemoteException e) {
13778                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13779                 }
13780                 sb.append("\n");
13781             }
13782         }
13783     }
13784
13785     private static String processClass(ProcessRecord process) {
13786         if (process == null || process.pid == MY_PID) {
13787             return "system_server";
13788         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13789             return "system_app";
13790         } else {
13791             return "data_app";
13792         }
13793     }
13794
13795     private volatile long mWtfClusterStart;
13796     private volatile int mWtfClusterCount;
13797
13798     /**
13799      * Write a description of an error (crash, WTF, ANR) to the drop box.
13800      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13801      * @param process which caused the error, null means the system server
13802      * @param activity which triggered the error, null if unknown
13803      * @param parent activity related to the error, null if unknown
13804      * @param subject line related to the error, null if absent
13805      * @param report in long form describing the error, null if absent
13806      * @param dataFile text file to include in the report, null if none
13807      * @param crashInfo giving an application stack trace, null if absent
13808      */
13809     public void addErrorToDropBox(String eventType,
13810             ProcessRecord process, String processName, ActivityRecord activity,
13811             ActivityRecord parent, String subject,
13812             final String report, final File dataFile,
13813             final ApplicationErrorReport.CrashInfo crashInfo) {
13814         // NOTE -- this must never acquire the ActivityManagerService lock,
13815         // otherwise the watchdog may be prevented from resetting the system.
13816
13817         final String dropboxTag = processClass(process) + "_" + eventType;
13818         final DropBoxManager dbox = (DropBoxManager)
13819                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13820
13821         // Exit early if the dropbox isn't configured to accept this report type.
13822         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13823
13824         // Rate-limit how often we're willing to do the heavy lifting below to
13825         // collect and record logs; currently 5 logs per 10 second period.
13826         final long now = SystemClock.elapsedRealtime();
13827         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13828             mWtfClusterStart = now;
13829             mWtfClusterCount = 1;
13830         } else {
13831             if (mWtfClusterCount++ >= 5) return;
13832         }
13833
13834         final StringBuilder sb = new StringBuilder(1024);
13835         appendDropBoxProcessHeaders(process, processName, sb);
13836         if (process != null) {
13837             sb.append("Foreground: ")
13838                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13839                     .append("\n");
13840         }
13841         if (activity != null) {
13842             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13843         }
13844         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13845             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13846         }
13847         if (parent != null && parent != activity) {
13848             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13849         }
13850         if (subject != null) {
13851             sb.append("Subject: ").append(subject).append("\n");
13852         }
13853         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13854         if (Debug.isDebuggerConnected()) {
13855             sb.append("Debugger: Connected\n");
13856         }
13857         sb.append("\n");
13858
13859         // Do the rest in a worker thread to avoid blocking the caller on I/O
13860         // (After this point, we shouldn't access AMS internal data structures.)
13861         Thread worker = new Thread("Error dump: " + dropboxTag) {
13862             @Override
13863             public void run() {
13864                 if (report != null) {
13865                     sb.append(report);
13866                 }
13867
13868                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13869                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13870                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13871                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13872
13873                 if (dataFile != null && maxDataFileSize > 0) {
13874                     try {
13875                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13876                                     "\n\n[[TRUNCATED]]"));
13877                     } catch (IOException e) {
13878                         Slog.e(TAG, "Error reading " + dataFile, e);
13879                     }
13880                 }
13881                 if (crashInfo != null && crashInfo.stackTrace != null) {
13882                     sb.append(crashInfo.stackTrace);
13883                 }
13884
13885                 if (lines > 0) {
13886                     sb.append("\n");
13887
13888                     // Merge several logcat streams, and take the last N lines
13889                     InputStreamReader input = null;
13890                     try {
13891                         java.lang.Process logcat = new ProcessBuilder(
13892                                 "/system/bin/timeout", "-k", "15s", "10s",
13893                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13894                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13895                                         .redirectErrorStream(true).start();
13896
13897                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13898                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13899                         input = new InputStreamReader(logcat.getInputStream());
13900
13901                         int num;
13902                         char[] buf = new char[8192];
13903                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13904                     } catch (IOException e) {
13905                         Slog.e(TAG, "Error running logcat", e);
13906                     } finally {
13907                         if (input != null) try { input.close(); } catch (IOException e) {}
13908                     }
13909                 }
13910
13911                 dbox.addText(dropboxTag, sb.toString());
13912             }
13913         };
13914
13915         if (process == null) {
13916             // If process is null, we are being called from some internal code
13917             // and may be about to die -- run this synchronously.
13918             worker.run();
13919         } else {
13920             worker.start();
13921         }
13922     }
13923
13924     @Override
13925     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13926         enforceNotIsolatedCaller("getProcessesInErrorState");
13927         // assume our apps are happy - lazy create the list
13928         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13929
13930         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13931                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13932         int userId = UserHandle.getUserId(Binder.getCallingUid());
13933
13934         synchronized (this) {
13935
13936             // iterate across all processes
13937             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13938                 ProcessRecord app = mLruProcesses.get(i);
13939                 if (!allUsers && app.userId != userId) {
13940                     continue;
13941                 }
13942                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13943                     // This one's in trouble, so we'll generate a report for it
13944                     // crashes are higher priority (in case there's a crash *and* an anr)
13945                     ActivityManager.ProcessErrorStateInfo report = null;
13946                     if (app.crashing) {
13947                         report = app.crashingReport;
13948                     } else if (app.notResponding) {
13949                         report = app.notRespondingReport;
13950                     }
13951
13952                     if (report != null) {
13953                         if (errList == null) {
13954                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13955                         }
13956                         errList.add(report);
13957                     } else {
13958                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13959                                 " crashing = " + app.crashing +
13960                                 " notResponding = " + app.notResponding);
13961                     }
13962                 }
13963             }
13964         }
13965
13966         return errList;
13967     }
13968
13969     static int procStateToImportance(int procState, int memAdj,
13970             ActivityManager.RunningAppProcessInfo currApp) {
13971         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13972         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13973             currApp.lru = memAdj;
13974         } else {
13975             currApp.lru = 0;
13976         }
13977         return imp;
13978     }
13979
13980     private void fillInProcMemInfo(ProcessRecord app,
13981             ActivityManager.RunningAppProcessInfo outInfo) {
13982         outInfo.pid = app.pid;
13983         outInfo.uid = app.info.uid;
13984         if (mHeavyWeightProcess == app) {
13985             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13986         }
13987         if (app.persistent) {
13988             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13989         }
13990         if (app.activities.size() > 0) {
13991             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13992         }
13993         outInfo.lastTrimLevel = app.trimMemoryLevel;
13994         int adj = app.curAdj;
13995         int procState = app.curProcState;
13996         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13997         outInfo.importanceReasonCode = app.adjTypeCode;
13998         outInfo.processState = app.curProcState;
13999     }
14000
14001     @Override
14002     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14003         enforceNotIsolatedCaller("getRunningAppProcesses");
14004
14005         final int callingUid = Binder.getCallingUid();
14006
14007         // Lazy instantiation of list
14008         List<ActivityManager.RunningAppProcessInfo> runList = null;
14009         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14010                 callingUid) == PackageManager.PERMISSION_GRANTED;
14011         final int userId = UserHandle.getUserId(callingUid);
14012         final boolean allUids = isGetTasksAllowed(
14013                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14014
14015         synchronized (this) {
14016             // Iterate across all processes
14017             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14018                 ProcessRecord app = mLruProcesses.get(i);
14019                 if ((!allUsers && app.userId != userId)
14020                         || (!allUids && app.uid != callingUid)) {
14021                     continue;
14022                 }
14023                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14024                     // Generate process state info for running application
14025                     ActivityManager.RunningAppProcessInfo currApp =
14026                         new ActivityManager.RunningAppProcessInfo(app.processName,
14027                                 app.pid, app.getPackageList());
14028                     fillInProcMemInfo(app, currApp);
14029                     if (app.adjSource instanceof ProcessRecord) {
14030                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14031                         currApp.importanceReasonImportance =
14032                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14033                                         app.adjSourceProcState);
14034                     } else if (app.adjSource instanceof ActivityRecord) {
14035                         ActivityRecord r = (ActivityRecord)app.adjSource;
14036                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14037                     }
14038                     if (app.adjTarget instanceof ComponentName) {
14039                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14040                     }
14041                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14042                     //        + " lru=" + currApp.lru);
14043                     if (runList == null) {
14044                         runList = new ArrayList<>();
14045                     }
14046                     runList.add(currApp);
14047                 }
14048             }
14049         }
14050         return runList;
14051     }
14052
14053     @Override
14054     public List<ApplicationInfo> getRunningExternalApplications() {
14055         enforceNotIsolatedCaller("getRunningExternalApplications");
14056         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14057         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14058         if (runningApps != null && runningApps.size() > 0) {
14059             Set<String> extList = new HashSet<String>();
14060             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14061                 if (app.pkgList != null) {
14062                     for (String pkg : app.pkgList) {
14063                         extList.add(pkg);
14064                     }
14065                 }
14066             }
14067             IPackageManager pm = AppGlobals.getPackageManager();
14068             for (String pkg : extList) {
14069                 try {
14070                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14071                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14072                         retList.add(info);
14073                     }
14074                 } catch (RemoteException e) {
14075                 }
14076             }
14077         }
14078         return retList;
14079     }
14080
14081     @Override
14082     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14083         enforceNotIsolatedCaller("getMyMemoryState");
14084         synchronized (this) {
14085             ProcessRecord proc;
14086             synchronized (mPidsSelfLocked) {
14087                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14088             }
14089             fillInProcMemInfo(proc, outInfo);
14090         }
14091     }
14092
14093     @Override
14094     public int getMemoryTrimLevel() {
14095         enforceNotIsolatedCaller("getMyMemoryState");
14096         synchronized (this) {
14097             return mLastMemoryLevel;
14098         }
14099     }
14100
14101     @Override
14102     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14103             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14104         (new ActivityManagerShellCommand(this, false)).exec(
14105                 this, in, out, err, args, resultReceiver);
14106     }
14107
14108     @Override
14109     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14110         if (checkCallingPermission(android.Manifest.permission.DUMP)
14111                 != PackageManager.PERMISSION_GRANTED) {
14112             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14113                     + Binder.getCallingPid()
14114                     + ", uid=" + Binder.getCallingUid()
14115                     + " without permission "
14116                     + android.Manifest.permission.DUMP);
14117             return;
14118         }
14119
14120         boolean dumpAll = false;
14121         boolean dumpClient = false;
14122         boolean dumpCheckin = false;
14123         boolean dumpCheckinFormat = false;
14124         String dumpPackage = null;
14125
14126         int opti = 0;
14127         while (opti < args.length) {
14128             String opt = args[opti];
14129             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14130                 break;
14131             }
14132             opti++;
14133             if ("-a".equals(opt)) {
14134                 dumpAll = true;
14135             } else if ("-c".equals(opt)) {
14136                 dumpClient = true;
14137             } else if ("-p".equals(opt)) {
14138                 if (opti < args.length) {
14139                     dumpPackage = args[opti];
14140                     opti++;
14141                 } else {
14142                     pw.println("Error: -p option requires package argument");
14143                     return;
14144                 }
14145                 dumpClient = true;
14146             } else if ("--checkin".equals(opt)) {
14147                 dumpCheckin = dumpCheckinFormat = true;
14148             } else if ("-C".equals(opt)) {
14149                 dumpCheckinFormat = true;
14150             } else if ("-h".equals(opt)) {
14151                 ActivityManagerShellCommand.dumpHelp(pw, true);
14152                 return;
14153             } else {
14154                 pw.println("Unknown argument: " + opt + "; use -h for help");
14155             }
14156         }
14157
14158         long origId = Binder.clearCallingIdentity();
14159         boolean more = false;
14160         // Is the caller requesting to dump a particular piece of data?
14161         if (opti < args.length) {
14162             String cmd = args[opti];
14163             opti++;
14164             if ("activities".equals(cmd) || "a".equals(cmd)) {
14165                 synchronized (this) {
14166                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14167                 }
14168             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14169                 synchronized (this) {
14170                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14171                 }
14172             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14173                 String[] newArgs;
14174                 String name;
14175                 if (opti >= args.length) {
14176                     name = null;
14177                     newArgs = EMPTY_STRING_ARRAY;
14178                 } else {
14179                     dumpPackage = args[opti];
14180                     opti++;
14181                     newArgs = new String[args.length - opti];
14182                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14183                             args.length - opti);
14184                 }
14185                 synchronized (this) {
14186                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14187                 }
14188             } else if ("broadcast-stats".equals(cmd)) {
14189                 String[] newArgs;
14190                 String name;
14191                 if (opti >= args.length) {
14192                     name = null;
14193                     newArgs = EMPTY_STRING_ARRAY;
14194                 } else {
14195                     dumpPackage = args[opti];
14196                     opti++;
14197                     newArgs = new String[args.length - opti];
14198                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14199                             args.length - opti);
14200                 }
14201                 synchronized (this) {
14202                     if (dumpCheckinFormat) {
14203                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14204                                 dumpPackage);
14205                     } else {
14206                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14207                     }
14208                 }
14209             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14210                 String[] newArgs;
14211                 String name;
14212                 if (opti >= args.length) {
14213                     name = null;
14214                     newArgs = EMPTY_STRING_ARRAY;
14215                 } else {
14216                     dumpPackage = args[opti];
14217                     opti++;
14218                     newArgs = new String[args.length - opti];
14219                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14220                             args.length - opti);
14221                 }
14222                 synchronized (this) {
14223                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14224                 }
14225             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14226                 String[] newArgs;
14227                 String name;
14228                 if (opti >= args.length) {
14229                     name = null;
14230                     newArgs = EMPTY_STRING_ARRAY;
14231                 } else {
14232                     dumpPackage = args[opti];
14233                     opti++;
14234                     newArgs = new String[args.length - opti];
14235                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14236                             args.length - opti);
14237                 }
14238                 synchronized (this) {
14239                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14240                 }
14241             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14242                 synchronized (this) {
14243                     dumpOomLocked(fd, pw, args, opti, true);
14244                 }
14245             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14246                 synchronized (this) {
14247                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14248                 }
14249             } else if ("provider".equals(cmd)) {
14250                 String[] newArgs;
14251                 String name;
14252                 if (opti >= args.length) {
14253                     name = null;
14254                     newArgs = EMPTY_STRING_ARRAY;
14255                 } else {
14256                     name = args[opti];
14257                     opti++;
14258                     newArgs = new String[args.length - opti];
14259                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14260                 }
14261                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14262                     pw.println("No providers match: " + name);
14263                     pw.println("Use -h for help.");
14264                 }
14265             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14266                 synchronized (this) {
14267                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14268                 }
14269             } else if ("service".equals(cmd)) {
14270                 String[] newArgs;
14271                 String name;
14272                 if (opti >= args.length) {
14273                     name = null;
14274                     newArgs = EMPTY_STRING_ARRAY;
14275                 } else {
14276                     name = args[opti];
14277                     opti++;
14278                     newArgs = new String[args.length - opti];
14279                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14280                             args.length - opti);
14281                 }
14282                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14283                     pw.println("No services match: " + name);
14284                     pw.println("Use -h for help.");
14285                 }
14286             } else if ("package".equals(cmd)) {
14287                 String[] newArgs;
14288                 if (opti >= args.length) {
14289                     pw.println("package: no package name specified");
14290                     pw.println("Use -h for help.");
14291                 } else {
14292                     dumpPackage = args[opti];
14293                     opti++;
14294                     newArgs = new String[args.length - opti];
14295                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14296                             args.length - opti);
14297                     args = newArgs;
14298                     opti = 0;
14299                     more = true;
14300                 }
14301             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14302                 synchronized (this) {
14303                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14304                 }
14305             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14306                 if (dumpClient) {
14307                     ActiveServices.ServiceDumper dumper;
14308                     synchronized (this) {
14309                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14310                                 dumpPackage);
14311                     }
14312                     dumper.dumpWithClient();
14313                 } else {
14314                     synchronized (this) {
14315                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14316                                 dumpPackage).dumpLocked();
14317                     }
14318                 }
14319             } else if ("locks".equals(cmd)) {
14320                 LockGuard.dump(fd, pw, args);
14321             } else {
14322                 // Dumping a single activity?
14323                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14324                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14325                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14326                     if (res < 0) {
14327                         pw.println("Bad activity command, or no activities match: " + cmd);
14328                         pw.println("Use -h for help.");
14329                     }
14330                 }
14331             }
14332             if (!more) {
14333                 Binder.restoreCallingIdentity(origId);
14334                 return;
14335             }
14336         }
14337
14338         // No piece of data specified, dump everything.
14339         if (dumpCheckinFormat) {
14340             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14341         } else if (dumpClient) {
14342             ActiveServices.ServiceDumper sdumper;
14343             synchronized (this) {
14344                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14345                 pw.println();
14346                 if (dumpAll) {
14347                     pw.println("-------------------------------------------------------------------------------");
14348                 }
14349                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14350                 pw.println();
14351                 if (dumpAll) {
14352                     pw.println("-------------------------------------------------------------------------------");
14353                 }
14354                 if (dumpAll || dumpPackage != null) {
14355                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14356                     pw.println();
14357                     if (dumpAll) {
14358                         pw.println("-------------------------------------------------------------------------------");
14359                     }
14360                 }
14361                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14362                 pw.println();
14363                 if (dumpAll) {
14364                     pw.println("-------------------------------------------------------------------------------");
14365                 }
14366                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14367                 pw.println();
14368                 if (dumpAll) {
14369                     pw.println("-------------------------------------------------------------------------------");
14370                 }
14371                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14372                         dumpPackage);
14373             }
14374             sdumper.dumpWithClient();
14375             pw.println();
14376             synchronized (this) {
14377                 if (dumpAll) {
14378                     pw.println("-------------------------------------------------------------------------------");
14379                 }
14380                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14381                 pw.println();
14382                 if (dumpAll) {
14383                     pw.println("-------------------------------------------------------------------------------");
14384                 }
14385                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14386                 if (mAssociations.size() > 0) {
14387                     pw.println();
14388                     if (dumpAll) {
14389                         pw.println("-------------------------------------------------------------------------------");
14390                     }
14391                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14392                 }
14393                 pw.println();
14394                 if (dumpAll) {
14395                     pw.println("-------------------------------------------------------------------------------");
14396                 }
14397                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14398             }
14399
14400         } else {
14401             synchronized (this) {
14402                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14403                 pw.println();
14404                 if (dumpAll) {
14405                     pw.println("-------------------------------------------------------------------------------");
14406                 }
14407                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14408                 pw.println();
14409                 if (dumpAll) {
14410                     pw.println("-------------------------------------------------------------------------------");
14411                 }
14412                 if (dumpAll || dumpPackage != null) {
14413                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14414                     pw.println();
14415                     if (dumpAll) {
14416                         pw.println("-------------------------------------------------------------------------------");
14417                     }
14418                 }
14419                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14420                 pw.println();
14421                 if (dumpAll) {
14422                     pw.println("-------------------------------------------------------------------------------");
14423                 }
14424                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14425                 pw.println();
14426                 if (dumpAll) {
14427                     pw.println("-------------------------------------------------------------------------------");
14428                 }
14429                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14430                         .dumpLocked();
14431                 pw.println();
14432                 if (dumpAll) {
14433                     pw.println("-------------------------------------------------------------------------------");
14434                 }
14435                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14436                 pw.println();
14437                 if (dumpAll) {
14438                     pw.println("-------------------------------------------------------------------------------");
14439                 }
14440                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14441                 if (mAssociations.size() > 0) {
14442                     pw.println();
14443                     if (dumpAll) {
14444                         pw.println("-------------------------------------------------------------------------------");
14445                     }
14446                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14447                 }
14448                 pw.println();
14449                 if (dumpAll) {
14450                     pw.println("-------------------------------------------------------------------------------");
14451                 }
14452                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14453             }
14454         }
14455         Binder.restoreCallingIdentity(origId);
14456     }
14457
14458     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14459             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14460         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14461
14462         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14463                 dumpPackage);
14464         boolean needSep = printedAnything;
14465
14466         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14467                 dumpPackage, needSep, "  mFocusedActivity: ");
14468         if (printed) {
14469             printedAnything = true;
14470             needSep = false;
14471         }
14472
14473         if (dumpPackage == null) {
14474             if (needSep) {
14475                 pw.println();
14476             }
14477             needSep = true;
14478             printedAnything = true;
14479             mStackSupervisor.dump(pw, "  ");
14480         }
14481
14482         if (!printedAnything) {
14483             pw.println("  (nothing)");
14484         }
14485     }
14486
14487     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14488             int opti, boolean dumpAll, String dumpPackage) {
14489         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14490
14491         boolean printedAnything = false;
14492
14493         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14494             boolean printedHeader = false;
14495
14496             final int N = mRecentTasks.size();
14497             for (int i=0; i<N; i++) {
14498                 TaskRecord tr = mRecentTasks.get(i);
14499                 if (dumpPackage != null) {
14500                     if (tr.realActivity == null ||
14501                             !dumpPackage.equals(tr.realActivity)) {
14502                         continue;
14503                     }
14504                 }
14505                 if (!printedHeader) {
14506                     pw.println("  Recent tasks:");
14507                     printedHeader = true;
14508                     printedAnything = true;
14509                 }
14510                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14511                         pw.println(tr);
14512                 if (dumpAll) {
14513                     mRecentTasks.get(i).dump(pw, "    ");
14514                 }
14515             }
14516         }
14517
14518         if (!printedAnything) {
14519             pw.println("  (nothing)");
14520         }
14521     }
14522
14523     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14524             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14525         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14526
14527         int dumpUid = 0;
14528         if (dumpPackage != null) {
14529             IPackageManager pm = AppGlobals.getPackageManager();
14530             try {
14531                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14532             } catch (RemoteException e) {
14533             }
14534         }
14535
14536         boolean printedAnything = false;
14537
14538         final long now = SystemClock.uptimeMillis();
14539
14540         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14541             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14542                     = mAssociations.valueAt(i1);
14543             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14544                 SparseArray<ArrayMap<String, Association>> sourceUids
14545                         = targetComponents.valueAt(i2);
14546                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14547                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14548                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14549                         Association ass = sourceProcesses.valueAt(i4);
14550                         if (dumpPackage != null) {
14551                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14552                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14553                                 continue;
14554                             }
14555                         }
14556                         printedAnything = true;
14557                         pw.print("  ");
14558                         pw.print(ass.mTargetProcess);
14559                         pw.print("/");
14560                         UserHandle.formatUid(pw, ass.mTargetUid);
14561                         pw.print(" <- ");
14562                         pw.print(ass.mSourceProcess);
14563                         pw.print("/");
14564                         UserHandle.formatUid(pw, ass.mSourceUid);
14565                         pw.println();
14566                         pw.print("    via ");
14567                         pw.print(ass.mTargetComponent.flattenToShortString());
14568                         pw.println();
14569                         pw.print("    ");
14570                         long dur = ass.mTime;
14571                         if (ass.mNesting > 0) {
14572                             dur += now - ass.mStartTime;
14573                         }
14574                         TimeUtils.formatDuration(dur, pw);
14575                         pw.print(" (");
14576                         pw.print(ass.mCount);
14577                         pw.print(" times)");
14578                         pw.print("  ");
14579                         for (int i=0; i<ass.mStateTimes.length; i++) {
14580                             long amt = ass.mStateTimes[i];
14581                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14582                                 amt += now - ass.mLastStateUptime;
14583                             }
14584                             if (amt != 0) {
14585                                 pw.print(" ");
14586                                 pw.print(ProcessList.makeProcStateString(
14587                                             i + ActivityManager.MIN_PROCESS_STATE));
14588                                 pw.print("=");
14589                                 TimeUtils.formatDuration(amt, pw);
14590                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14591                                     pw.print("*");
14592                                 }
14593                             }
14594                         }
14595                         pw.println();
14596                         if (ass.mNesting > 0) {
14597                             pw.print("    Currently active: ");
14598                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14599                             pw.println();
14600                         }
14601                     }
14602                 }
14603             }
14604
14605         }
14606
14607         if (!printedAnything) {
14608             pw.println("  (nothing)");
14609         }
14610     }
14611
14612     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14613             String header, boolean needSep) {
14614         boolean printed = false;
14615         int whichAppId = -1;
14616         if (dumpPackage != null) {
14617             try {
14618                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14619                         dumpPackage, 0);
14620                 whichAppId = UserHandle.getAppId(info.uid);
14621             } catch (NameNotFoundException e) {
14622                 e.printStackTrace();
14623             }
14624         }
14625         for (int i=0; i<uids.size(); i++) {
14626             UidRecord uidRec = uids.valueAt(i);
14627             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14628                 continue;
14629             }
14630             if (!printed) {
14631                 printed = true;
14632                 if (needSep) {
14633                     pw.println();
14634                 }
14635                 pw.print("  ");
14636                 pw.println(header);
14637                 needSep = true;
14638             }
14639             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14640             pw.print(": "); pw.println(uidRec);
14641         }
14642         return printed;
14643     }
14644
14645     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14646             int opti, boolean dumpAll, String dumpPackage) {
14647         boolean needSep = false;
14648         boolean printedAnything = false;
14649         int numPers = 0;
14650
14651         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14652
14653         if (dumpAll) {
14654             final int NP = mProcessNames.getMap().size();
14655             for (int ip=0; ip<NP; ip++) {
14656                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14657                 final int NA = procs.size();
14658                 for (int ia=0; ia<NA; ia++) {
14659                     ProcessRecord r = procs.valueAt(ia);
14660                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14661                         continue;
14662                     }
14663                     if (!needSep) {
14664                         pw.println("  All known processes:");
14665                         needSep = true;
14666                         printedAnything = true;
14667                     }
14668                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14669                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14670                         pw.print(" "); pw.println(r);
14671                     r.dump(pw, "    ");
14672                     if (r.persistent) {
14673                         numPers++;
14674                     }
14675                 }
14676             }
14677         }
14678
14679         if (mIsolatedProcesses.size() > 0) {
14680             boolean printed = false;
14681             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14682                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14683                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14684                     continue;
14685                 }
14686                 if (!printed) {
14687                     if (needSep) {
14688                         pw.println();
14689                     }
14690                     pw.println("  Isolated process list (sorted by uid):");
14691                     printedAnything = true;
14692                     printed = true;
14693                     needSep = true;
14694                 }
14695                 pw.println(String.format("%sIsolated #%2d: %s",
14696                         "    ", i, r.toString()));
14697             }
14698         }
14699
14700         if (mActiveUids.size() > 0) {
14701             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14702                 printedAnything = needSep = true;
14703             }
14704         }
14705         if (mValidateUids.size() > 0) {
14706             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14707                 printedAnything = needSep = true;
14708             }
14709         }
14710
14711         if (mLruProcesses.size() > 0) {
14712             if (needSep) {
14713                 pw.println();
14714             }
14715             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14716                     pw.print(" total, non-act at ");
14717                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14718                     pw.print(", non-svc at ");
14719                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14720                     pw.println("):");
14721             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14722             needSep = true;
14723             printedAnything = true;
14724         }
14725
14726         if (dumpAll || dumpPackage != null) {
14727             synchronized (mPidsSelfLocked) {
14728                 boolean printed = false;
14729                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14730                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14731                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14732                         continue;
14733                     }
14734                     if (!printed) {
14735                         if (needSep) pw.println();
14736                         needSep = true;
14737                         pw.println("  PID mappings:");
14738                         printed = true;
14739                         printedAnything = true;
14740                     }
14741                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14742                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14743                 }
14744             }
14745         }
14746
14747         if (mForegroundProcesses.size() > 0) {
14748             synchronized (mPidsSelfLocked) {
14749                 boolean printed = false;
14750                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14751                     ProcessRecord r = mPidsSelfLocked.get(
14752                             mForegroundProcesses.valueAt(i).pid);
14753                     if (dumpPackage != null && (r == null
14754                             || !r.pkgList.containsKey(dumpPackage))) {
14755                         continue;
14756                     }
14757                     if (!printed) {
14758                         if (needSep) pw.println();
14759                         needSep = true;
14760                         pw.println("  Foreground Processes:");
14761                         printed = true;
14762                         printedAnything = true;
14763                     }
14764                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14765                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14766                 }
14767             }
14768         }
14769
14770         if (mPersistentStartingProcesses.size() > 0) {
14771             if (needSep) pw.println();
14772             needSep = true;
14773             printedAnything = true;
14774             pw.println("  Persisent processes that are starting:");
14775             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14776                     "Starting Norm", "Restarting PERS", dumpPackage);
14777         }
14778
14779         if (mRemovedProcesses.size() > 0) {
14780             if (needSep) pw.println();
14781             needSep = true;
14782             printedAnything = true;
14783             pw.println("  Processes that are being removed:");
14784             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14785                     "Removed Norm", "Removed PERS", dumpPackage);
14786         }
14787
14788         if (mProcessesOnHold.size() > 0) {
14789             if (needSep) pw.println();
14790             needSep = true;
14791             printedAnything = true;
14792             pw.println("  Processes that are on old until the system is ready:");
14793             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14794                     "OnHold Norm", "OnHold PERS", dumpPackage);
14795         }
14796
14797         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14798
14799         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14800         if (needSep) {
14801             printedAnything = true;
14802         }
14803
14804         if (dumpPackage == null) {
14805             pw.println();
14806             needSep = false;
14807             mUserController.dump(pw, dumpAll);
14808         }
14809         if (mHomeProcess != null && (dumpPackage == null
14810                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14811             if (needSep) {
14812                 pw.println();
14813                 needSep = false;
14814             }
14815             pw.println("  mHomeProcess: " + mHomeProcess);
14816         }
14817         if (mPreviousProcess != null && (dumpPackage == null
14818                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14819             if (needSep) {
14820                 pw.println();
14821                 needSep = false;
14822             }
14823             pw.println("  mPreviousProcess: " + mPreviousProcess);
14824         }
14825         if (dumpAll) {
14826             StringBuilder sb = new StringBuilder(128);
14827             sb.append("  mPreviousProcessVisibleTime: ");
14828             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14829             pw.println(sb);
14830         }
14831         if (mHeavyWeightProcess != null && (dumpPackage == null
14832                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14833             if (needSep) {
14834                 pw.println();
14835                 needSep = false;
14836             }
14837             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14838         }
14839         if (dumpPackage == null) {
14840             pw.println("  mConfiguration: " + mConfiguration);
14841         }
14842         if (dumpAll) {
14843             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14844             if (mCompatModePackages.getPackages().size() > 0) {
14845                 boolean printed = false;
14846                 for (Map.Entry<String, Integer> entry
14847                         : mCompatModePackages.getPackages().entrySet()) {
14848                     String pkg = entry.getKey();
14849                     int mode = entry.getValue();
14850                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14851                         continue;
14852                     }
14853                     if (!printed) {
14854                         pw.println("  mScreenCompatPackages:");
14855                         printed = true;
14856                     }
14857                     pw.print("    "); pw.print(pkg); pw.print(": ");
14858                             pw.print(mode); pw.println();
14859                 }
14860             }
14861         }
14862         if (dumpPackage == null) {
14863             pw.println("  mWakefulness="
14864                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14865             pw.println("  mSleepTokens=" + mSleepTokens);
14866             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14867                     + lockScreenShownToString());
14868             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14869             if (mRunningVoice != null) {
14870                 pw.println("  mRunningVoice=" + mRunningVoice);
14871                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14872             }
14873         }
14874         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14875                 || mOrigWaitForDebugger) {
14876             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14877                     || dumpPackage.equals(mOrigDebugApp)) {
14878                 if (needSep) {
14879                     pw.println();
14880                     needSep = false;
14881                 }
14882                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14883                         + " mDebugTransient=" + mDebugTransient
14884                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14885             }
14886         }
14887         if (mCurAppTimeTracker != null) {
14888             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14889         }
14890         if (mMemWatchProcesses.getMap().size() > 0) {
14891             pw.println("  Mem watch processes:");
14892             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14893                     = mMemWatchProcesses.getMap();
14894             for (int i=0; i<procs.size(); i++) {
14895                 final String proc = procs.keyAt(i);
14896                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14897                 for (int j=0; j<uids.size(); j++) {
14898                     if (needSep) {
14899                         pw.println();
14900                         needSep = false;
14901                     }
14902                     StringBuilder sb = new StringBuilder();
14903                     sb.append("    ").append(proc).append('/');
14904                     UserHandle.formatUid(sb, uids.keyAt(j));
14905                     Pair<Long, String> val = uids.valueAt(j);
14906                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14907                     if (val.second != null) {
14908                         sb.append(", report to ").append(val.second);
14909                     }
14910                     pw.println(sb.toString());
14911                 }
14912             }
14913             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14914             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14915             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14916                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14917         }
14918         if (mTrackAllocationApp != null) {
14919             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14920                 if (needSep) {
14921                     pw.println();
14922                     needSep = false;
14923                 }
14924                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14925             }
14926         }
14927         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14928                 || mProfileFd != null) {
14929             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14930                 if (needSep) {
14931                     pw.println();
14932                     needSep = false;
14933                 }
14934                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14935                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14936                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14937                         + mAutoStopProfiler);
14938                 pw.println("  mProfileType=" + mProfileType);
14939             }
14940         }
14941         if (mNativeDebuggingApp != null) {
14942             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14943                 if (needSep) {
14944                     pw.println();
14945                     needSep = false;
14946                 }
14947                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14948             }
14949         }
14950         if (dumpPackage == null) {
14951             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14952                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14953                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14954             }
14955             if (mController != null) {
14956                 pw.println("  mController=" + mController
14957                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14958             }
14959             if (dumpAll) {
14960                 pw.println("  Total persistent processes: " + numPers);
14961                 pw.println("  mProcessesReady=" + mProcessesReady
14962                         + " mSystemReady=" + mSystemReady
14963                         + " mBooted=" + mBooted
14964                         + " mFactoryTest=" + mFactoryTest);
14965                 pw.println("  mBooting=" + mBooting
14966                         + " mCallFinishBooting=" + mCallFinishBooting
14967                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14968                 pw.print("  mLastPowerCheckRealtime=");
14969                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14970                         pw.println("");
14971                 pw.print("  mLastPowerCheckUptime=");
14972                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14973                         pw.println("");
14974                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14975                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14976                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14977                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14978                         + " (" + mLruProcesses.size() + " total)"
14979                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14980                         + " mNumServiceProcs=" + mNumServiceProcs
14981                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14982                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14983                         + " mLastMemoryLevel=" + mLastMemoryLevel
14984                         + " mLastNumProcesses=" + mLastNumProcesses);
14985                 long now = SystemClock.uptimeMillis();
14986                 pw.print("  mLastIdleTime=");
14987                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14988                         pw.print(" mLowRamSinceLastIdle=");
14989                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14990                         pw.println();
14991             }
14992         }
14993
14994         if (!printedAnything) {
14995             pw.println("  (nothing)");
14996         }
14997     }
14998
14999     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15000             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15001         if (mProcessesToGc.size() > 0) {
15002             boolean printed = false;
15003             long now = SystemClock.uptimeMillis();
15004             for (int i=0; i<mProcessesToGc.size(); i++) {
15005                 ProcessRecord proc = mProcessesToGc.get(i);
15006                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15007                     continue;
15008                 }
15009                 if (!printed) {
15010                     if (needSep) pw.println();
15011                     needSep = true;
15012                     pw.println("  Processes that are waiting to GC:");
15013                     printed = true;
15014                 }
15015                 pw.print("    Process "); pw.println(proc);
15016                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15017                         pw.print(", last gced=");
15018                         pw.print(now-proc.lastRequestedGc);
15019                         pw.print(" ms ago, last lowMem=");
15020                         pw.print(now-proc.lastLowMemory);
15021                         pw.println(" ms ago");
15022
15023             }
15024         }
15025         return needSep;
15026     }
15027
15028     void printOomLevel(PrintWriter pw, String name, int adj) {
15029         pw.print("    ");
15030         if (adj >= 0) {
15031             pw.print(' ');
15032             if (adj < 10) pw.print(' ');
15033         } else {
15034             if (adj > -10) pw.print(' ');
15035         }
15036         pw.print(adj);
15037         pw.print(": ");
15038         pw.print(name);
15039         pw.print(" (");
15040         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15041         pw.println(")");
15042     }
15043
15044     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15045             int opti, boolean dumpAll) {
15046         boolean needSep = false;
15047
15048         if (mLruProcesses.size() > 0) {
15049             if (needSep) pw.println();
15050             needSep = true;
15051             pw.println("  OOM levels:");
15052             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15053             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15054             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15055             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15056             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15057             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15058             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15059             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15060             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15061             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15062             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15063             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15064             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15065             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15066
15067             if (needSep) pw.println();
15068             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15069                     pw.print(" total, non-act at ");
15070                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15071                     pw.print(", non-svc at ");
15072                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15073                     pw.println("):");
15074             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15075             needSep = true;
15076         }
15077
15078         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15079
15080         pw.println();
15081         pw.println("  mHomeProcess: " + mHomeProcess);
15082         pw.println("  mPreviousProcess: " + mPreviousProcess);
15083         if (mHeavyWeightProcess != null) {
15084             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15085         }
15086
15087         return true;
15088     }
15089
15090     /**
15091      * There are three ways to call this:
15092      *  - no provider specified: dump all the providers
15093      *  - a flattened component name that matched an existing provider was specified as the
15094      *    first arg: dump that one provider
15095      *  - the first arg isn't the flattened component name of an existing provider:
15096      *    dump all providers whose component contains the first arg as a substring
15097      */
15098     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15099             int opti, boolean dumpAll) {
15100         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15101     }
15102
15103     static class ItemMatcher {
15104         ArrayList<ComponentName> components;
15105         ArrayList<String> strings;
15106         ArrayList<Integer> objects;
15107         boolean all;
15108
15109         ItemMatcher() {
15110             all = true;
15111         }
15112
15113         void build(String name) {
15114             ComponentName componentName = ComponentName.unflattenFromString(name);
15115             if (componentName != null) {
15116                 if (components == null) {
15117                     components = new ArrayList<ComponentName>();
15118                 }
15119                 components.add(componentName);
15120                 all = false;
15121             } else {
15122                 int objectId = 0;
15123                 // Not a '/' separated full component name; maybe an object ID?
15124                 try {
15125                     objectId = Integer.parseInt(name, 16);
15126                     if (objects == null) {
15127                         objects = new ArrayList<Integer>();
15128                     }
15129                     objects.add(objectId);
15130                     all = false;
15131                 } catch (RuntimeException e) {
15132                     // Not an integer; just do string match.
15133                     if (strings == null) {
15134                         strings = new ArrayList<String>();
15135                     }
15136                     strings.add(name);
15137                     all = false;
15138                 }
15139             }
15140         }
15141
15142         int build(String[] args, int opti) {
15143             for (; opti<args.length; opti++) {
15144                 String name = args[opti];
15145                 if ("--".equals(name)) {
15146                     return opti+1;
15147                 }
15148                 build(name);
15149             }
15150             return opti;
15151         }
15152
15153         boolean match(Object object, ComponentName comp) {
15154             if (all) {
15155                 return true;
15156             }
15157             if (components != null) {
15158                 for (int i=0; i<components.size(); i++) {
15159                     if (components.get(i).equals(comp)) {
15160                         return true;
15161                     }
15162                 }
15163             }
15164             if (objects != null) {
15165                 for (int i=0; i<objects.size(); i++) {
15166                     if (System.identityHashCode(object) == objects.get(i)) {
15167                         return true;
15168                     }
15169                 }
15170             }
15171             if (strings != null) {
15172                 String flat = comp.flattenToString();
15173                 for (int i=0; i<strings.size(); i++) {
15174                     if (flat.contains(strings.get(i))) {
15175                         return true;
15176                     }
15177                 }
15178             }
15179             return false;
15180         }
15181     }
15182
15183     /**
15184      * There are three things that cmd can be:
15185      *  - a flattened component name that matches an existing activity
15186      *  - the cmd arg isn't the flattened component name of an existing activity:
15187      *    dump all activity whose component contains the cmd as a substring
15188      *  - A hex number of the ActivityRecord object instance.
15189      */
15190     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15191             int opti, boolean dumpAll) {
15192         ArrayList<ActivityRecord> activities;
15193
15194         synchronized (this) {
15195             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15196         }
15197
15198         if (activities.size() <= 0) {
15199             return false;
15200         }
15201
15202         String[] newArgs = new String[args.length - opti];
15203         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15204
15205         TaskRecord lastTask = null;
15206         boolean needSep = false;
15207         for (int i=activities.size()-1; i>=0; i--) {
15208             ActivityRecord r = activities.get(i);
15209             if (needSep) {
15210                 pw.println();
15211             }
15212             needSep = true;
15213             synchronized (this) {
15214                 if (lastTask != r.task) {
15215                     lastTask = r.task;
15216                     pw.print("TASK "); pw.print(lastTask.affinity);
15217                             pw.print(" id="); pw.println(lastTask.taskId);
15218                     if (dumpAll) {
15219                         lastTask.dump(pw, "  ");
15220                     }
15221                 }
15222             }
15223             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15224         }
15225         return true;
15226     }
15227
15228     /**
15229      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15230      * there is a thread associated with the activity.
15231      */
15232     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15233             final ActivityRecord r, String[] args, boolean dumpAll) {
15234         String innerPrefix = prefix + "  ";
15235         synchronized (this) {
15236             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15237                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15238                     pw.print(" pid=");
15239                     if (r.app != null) pw.println(r.app.pid);
15240                     else pw.println("(not running)");
15241             if (dumpAll) {
15242                 r.dump(pw, innerPrefix);
15243             }
15244         }
15245         if (r.app != null && r.app.thread != null) {
15246             // flush anything that is already in the PrintWriter since the thread is going
15247             // to write to the file descriptor directly
15248             pw.flush();
15249             try {
15250                 TransferPipe tp = new TransferPipe();
15251                 try {
15252                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15253                             r.appToken, innerPrefix, args);
15254                     tp.go(fd);
15255                 } finally {
15256                     tp.kill();
15257                 }
15258             } catch (IOException e) {
15259                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15260             } catch (RemoteException e) {
15261                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15262             }
15263         }
15264     }
15265
15266     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15267             int opti, boolean dumpAll, String dumpPackage) {
15268         boolean needSep = false;
15269         boolean onlyHistory = false;
15270         boolean printedAnything = false;
15271
15272         if ("history".equals(dumpPackage)) {
15273             if (opti < args.length && "-s".equals(args[opti])) {
15274                 dumpAll = false;
15275             }
15276             onlyHistory = true;
15277             dumpPackage = null;
15278         }
15279
15280         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15281         if (!onlyHistory && dumpAll) {
15282             if (mRegisteredReceivers.size() > 0) {
15283                 boolean printed = false;
15284                 Iterator it = mRegisteredReceivers.values().iterator();
15285                 while (it.hasNext()) {
15286                     ReceiverList r = (ReceiverList)it.next();
15287                     if (dumpPackage != null && (r.app == null ||
15288                             !dumpPackage.equals(r.app.info.packageName))) {
15289                         continue;
15290                     }
15291                     if (!printed) {
15292                         pw.println("  Registered Receivers:");
15293                         needSep = true;
15294                         printed = true;
15295                         printedAnything = true;
15296                     }
15297                     pw.print("  * "); pw.println(r);
15298                     r.dump(pw, "    ");
15299                 }
15300             }
15301
15302             if (mReceiverResolver.dump(pw, needSep ?
15303                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15304                     "    ", dumpPackage, false, false)) {
15305                 needSep = true;
15306                 printedAnything = true;
15307             }
15308         }
15309
15310         for (BroadcastQueue q : mBroadcastQueues) {
15311             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15312             printedAnything |= needSep;
15313         }
15314
15315         needSep = true;
15316
15317         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15318             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15319                 if (needSep) {
15320                     pw.println();
15321                 }
15322                 needSep = true;
15323                 printedAnything = true;
15324                 pw.print("  Sticky broadcasts for user ");
15325                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15326                 StringBuilder sb = new StringBuilder(128);
15327                 for (Map.Entry<String, ArrayList<Intent>> ent
15328                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15329                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15330                     if (dumpAll) {
15331                         pw.println(":");
15332                         ArrayList<Intent> intents = ent.getValue();
15333                         final int N = intents.size();
15334                         for (int i=0; i<N; i++) {
15335                             sb.setLength(0);
15336                             sb.append("    Intent: ");
15337                             intents.get(i).toShortString(sb, false, true, false, false);
15338                             pw.println(sb.toString());
15339                             Bundle bundle = intents.get(i).getExtras();
15340                             if (bundle != null) {
15341                                 pw.print("      ");
15342                                 pw.println(bundle.toString());
15343                             }
15344                         }
15345                     } else {
15346                         pw.println("");
15347                     }
15348                 }
15349             }
15350         }
15351
15352         if (!onlyHistory && dumpAll) {
15353             pw.println();
15354             for (BroadcastQueue queue : mBroadcastQueues) {
15355                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15356                         + queue.mBroadcastsScheduled);
15357             }
15358             pw.println("  mHandler:");
15359             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15360             needSep = true;
15361             printedAnything = true;
15362         }
15363
15364         if (!printedAnything) {
15365             pw.println("  (nothing)");
15366         }
15367     }
15368
15369     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15370             int opti, boolean dumpAll, String dumpPackage) {
15371         if (mCurBroadcastStats == null) {
15372             return;
15373         }
15374
15375         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15376         final long now = SystemClock.elapsedRealtime();
15377         if (mLastBroadcastStats != null) {
15378             pw.print("  Last stats (from ");
15379             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15380             pw.print(" to ");
15381             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15382             pw.print(", ");
15383             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15384                     - mLastBroadcastStats.mStartUptime, pw);
15385             pw.println(" uptime):");
15386             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15387                 pw.println("    (nothing)");
15388             }
15389             pw.println();
15390         }
15391         pw.print("  Current stats (from ");
15392         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15393         pw.print(" to now, ");
15394         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15395                 - mCurBroadcastStats.mStartUptime, pw);
15396         pw.println(" uptime):");
15397         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15398             pw.println("    (nothing)");
15399         }
15400     }
15401
15402     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15403             int opti, boolean fullCheckin, String dumpPackage) {
15404         if (mCurBroadcastStats == null) {
15405             return;
15406         }
15407
15408         if (mLastBroadcastStats != null) {
15409             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15410             if (fullCheckin) {
15411                 mLastBroadcastStats = null;
15412                 return;
15413             }
15414         }
15415         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15416         if (fullCheckin) {
15417             mCurBroadcastStats = null;
15418         }
15419     }
15420
15421     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15422             int opti, boolean dumpAll, String dumpPackage) {
15423         boolean needSep;
15424         boolean printedAnything = false;
15425
15426         ItemMatcher matcher = new ItemMatcher();
15427         matcher.build(args, opti);
15428
15429         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15430
15431         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15432         printedAnything |= needSep;
15433
15434         if (mLaunchingProviders.size() > 0) {
15435             boolean printed = false;
15436             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15437                 ContentProviderRecord r = mLaunchingProviders.get(i);
15438                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15439                     continue;
15440                 }
15441                 if (!printed) {
15442                     if (needSep) pw.println();
15443                     needSep = true;
15444                     pw.println("  Launching content providers:");
15445                     printed = true;
15446                     printedAnything = true;
15447                 }
15448                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15449                         pw.println(r);
15450             }
15451         }
15452
15453         if (!printedAnything) {
15454             pw.println("  (nothing)");
15455         }
15456     }
15457
15458     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15459             int opti, boolean dumpAll, String dumpPackage) {
15460         boolean needSep = false;
15461         boolean printedAnything = false;
15462
15463         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15464
15465         if (mGrantedUriPermissions.size() > 0) {
15466             boolean printed = false;
15467             int dumpUid = -2;
15468             if (dumpPackage != null) {
15469                 try {
15470                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15471                             MATCH_UNINSTALLED_PACKAGES, 0);
15472                 } catch (NameNotFoundException e) {
15473                     dumpUid = -1;
15474                 }
15475             }
15476             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15477                 int uid = mGrantedUriPermissions.keyAt(i);
15478                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15479                     continue;
15480                 }
15481                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15482                 if (!printed) {
15483                     if (needSep) pw.println();
15484                     needSep = true;
15485                     pw.println("  Granted Uri Permissions:");
15486                     printed = true;
15487                     printedAnything = true;
15488                 }
15489                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15490                 for (UriPermission perm : perms.values()) {
15491                     pw.print("    "); pw.println(perm);
15492                     if (dumpAll) {
15493                         perm.dump(pw, "      ");
15494                     }
15495                 }
15496             }
15497         }
15498
15499         if (!printedAnything) {
15500             pw.println("  (nothing)");
15501         }
15502     }
15503
15504     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15505             int opti, boolean dumpAll, String dumpPackage) {
15506         boolean printed = false;
15507
15508         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15509
15510         if (mIntentSenderRecords.size() > 0) {
15511             Iterator<WeakReference<PendingIntentRecord>> it
15512                     = mIntentSenderRecords.values().iterator();
15513             while (it.hasNext()) {
15514                 WeakReference<PendingIntentRecord> ref = it.next();
15515                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15516                 if (dumpPackage != null && (rec == null
15517                         || !dumpPackage.equals(rec.key.packageName))) {
15518                     continue;
15519                 }
15520                 printed = true;
15521                 if (rec != null) {
15522                     pw.print("  * "); pw.println(rec);
15523                     if (dumpAll) {
15524                         rec.dump(pw, "    ");
15525                     }
15526                 } else {
15527                     pw.print("  * "); pw.println(ref);
15528                 }
15529             }
15530         }
15531
15532         if (!printed) {
15533             pw.println("  (nothing)");
15534         }
15535     }
15536
15537     private static final int dumpProcessList(PrintWriter pw,
15538             ActivityManagerService service, List list,
15539             String prefix, String normalLabel, String persistentLabel,
15540             String dumpPackage) {
15541         int numPers = 0;
15542         final int N = list.size()-1;
15543         for (int i=N; i>=0; i--) {
15544             ProcessRecord r = (ProcessRecord)list.get(i);
15545             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15546                 continue;
15547             }
15548             pw.println(String.format("%s%s #%2d: %s",
15549                     prefix, (r.persistent ? persistentLabel : normalLabel),
15550                     i, r.toString()));
15551             if (r.persistent) {
15552                 numPers++;
15553             }
15554         }
15555         return numPers;
15556     }
15557
15558     private static final boolean dumpProcessOomList(PrintWriter pw,
15559             ActivityManagerService service, List<ProcessRecord> origList,
15560             String prefix, String normalLabel, String persistentLabel,
15561             boolean inclDetails, String dumpPackage) {
15562
15563         ArrayList<Pair<ProcessRecord, Integer>> list
15564                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15565         for (int i=0; i<origList.size(); i++) {
15566             ProcessRecord r = origList.get(i);
15567             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15568                 continue;
15569             }
15570             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15571         }
15572
15573         if (list.size() <= 0) {
15574             return false;
15575         }
15576
15577         Comparator<Pair<ProcessRecord, Integer>> comparator
15578                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15579             @Override
15580             public int compare(Pair<ProcessRecord, Integer> object1,
15581                     Pair<ProcessRecord, Integer> object2) {
15582                 if (object1.first.setAdj != object2.first.setAdj) {
15583                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15584                 }
15585                 if (object1.first.setProcState != object2.first.setProcState) {
15586                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15587                 }
15588                 if (object1.second.intValue() != object2.second.intValue()) {
15589                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15590                 }
15591                 return 0;
15592             }
15593         };
15594
15595         Collections.sort(list, comparator);
15596
15597         final long curRealtime = SystemClock.elapsedRealtime();
15598         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15599         final long curUptime = SystemClock.uptimeMillis();
15600         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15601
15602         for (int i=list.size()-1; i>=0; i--) {
15603             ProcessRecord r = list.get(i).first;
15604             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15605             char schedGroup;
15606             switch (r.setSchedGroup) {
15607                 case ProcessList.SCHED_GROUP_BACKGROUND:
15608                     schedGroup = 'B';
15609                     break;
15610                 case ProcessList.SCHED_GROUP_DEFAULT:
15611                     schedGroup = 'F';
15612                     break;
15613                 case ProcessList.SCHED_GROUP_TOP_APP:
15614                     schedGroup = 'T';
15615                     break;
15616                 default:
15617                     schedGroup = '?';
15618                     break;
15619             }
15620             char foreground;
15621             if (r.foregroundActivities) {
15622                 foreground = 'A';
15623             } else if (r.foregroundServices) {
15624                 foreground = 'S';
15625             } else {
15626                 foreground = ' ';
15627             }
15628             String procState = ProcessList.makeProcStateString(r.curProcState);
15629             pw.print(prefix);
15630             pw.print(r.persistent ? persistentLabel : normalLabel);
15631             pw.print(" #");
15632             int num = (origList.size()-1)-list.get(i).second;
15633             if (num < 10) pw.print(' ');
15634             pw.print(num);
15635             pw.print(": ");
15636             pw.print(oomAdj);
15637             pw.print(' ');
15638             pw.print(schedGroup);
15639             pw.print('/');
15640             pw.print(foreground);
15641             pw.print('/');
15642             pw.print(procState);
15643             pw.print(" trm:");
15644             if (r.trimMemoryLevel < 10) pw.print(' ');
15645             pw.print(r.trimMemoryLevel);
15646             pw.print(' ');
15647             pw.print(r.toShortString());
15648             pw.print(" (");
15649             pw.print(r.adjType);
15650             pw.println(')');
15651             if (r.adjSource != null || r.adjTarget != null) {
15652                 pw.print(prefix);
15653                 pw.print("    ");
15654                 if (r.adjTarget instanceof ComponentName) {
15655                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15656                 } else if (r.adjTarget != null) {
15657                     pw.print(r.adjTarget.toString());
15658                 } else {
15659                     pw.print("{null}");
15660                 }
15661                 pw.print("<=");
15662                 if (r.adjSource instanceof ProcessRecord) {
15663                     pw.print("Proc{");
15664                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15665                     pw.println("}");
15666                 } else if (r.adjSource != null) {
15667                     pw.println(r.adjSource.toString());
15668                 } else {
15669                     pw.println("{null}");
15670                 }
15671             }
15672             if (inclDetails) {
15673                 pw.print(prefix);
15674                 pw.print("    ");
15675                 pw.print("oom: max="); pw.print(r.maxAdj);
15676                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15677                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15678                 pw.print(" cur="); pw.print(r.curAdj);
15679                 pw.print(" set="); pw.println(r.setAdj);
15680                 pw.print(prefix);
15681                 pw.print("    ");
15682                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15683                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15684                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15685                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15686                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15687                 pw.println();
15688                 pw.print(prefix);
15689                 pw.print("    ");
15690                 pw.print("cached="); pw.print(r.cached);
15691                 pw.print(" empty="); pw.print(r.empty);
15692                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15693
15694                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15695                     if (r.lastWakeTime != 0) {
15696                         long wtime;
15697                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15698                         synchronized (stats) {
15699                             wtime = stats.getProcessWakeTime(r.info.uid,
15700                                     r.pid, curRealtime);
15701                         }
15702                         long timeUsed = wtime - r.lastWakeTime;
15703                         pw.print(prefix);
15704                         pw.print("    ");
15705                         pw.print("keep awake over ");
15706                         TimeUtils.formatDuration(realtimeSince, pw);
15707                         pw.print(" used ");
15708                         TimeUtils.formatDuration(timeUsed, pw);
15709                         pw.print(" (");
15710                         pw.print((timeUsed*100)/realtimeSince);
15711                         pw.println("%)");
15712                     }
15713                     if (r.lastCpuTime != 0) {
15714                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15715                         pw.print(prefix);
15716                         pw.print("    ");
15717                         pw.print("run cpu over ");
15718                         TimeUtils.formatDuration(uptimeSince, pw);
15719                         pw.print(" used ");
15720                         TimeUtils.formatDuration(timeUsed, pw);
15721                         pw.print(" (");
15722                         pw.print((timeUsed*100)/uptimeSince);
15723                         pw.println("%)");
15724                     }
15725                 }
15726             }
15727         }
15728         return true;
15729     }
15730
15731     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15732             String[] args) {
15733         ArrayList<ProcessRecord> procs;
15734         synchronized (this) {
15735             if (args != null && args.length > start
15736                     && args[start].charAt(0) != '-') {
15737                 procs = new ArrayList<ProcessRecord>();
15738                 int pid = -1;
15739                 try {
15740                     pid = Integer.parseInt(args[start]);
15741                 } catch (NumberFormatException e) {
15742                 }
15743                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15744                     ProcessRecord proc = mLruProcesses.get(i);
15745                     if (proc.pid == pid) {
15746                         procs.add(proc);
15747                     } else if (allPkgs && proc.pkgList != null
15748                             && proc.pkgList.containsKey(args[start])) {
15749                         procs.add(proc);
15750                     } else if (proc.processName.equals(args[start])) {
15751                         procs.add(proc);
15752                     }
15753                 }
15754                 if (procs.size() <= 0) {
15755                     return null;
15756                 }
15757             } else {
15758                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15759             }
15760         }
15761         return procs;
15762     }
15763
15764     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15765             PrintWriter pw, String[] args) {
15766         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15767         if (procs == null) {
15768             pw.println("No process found for: " + args[0]);
15769             return;
15770         }
15771
15772         long uptime = SystemClock.uptimeMillis();
15773         long realtime = SystemClock.elapsedRealtime();
15774         pw.println("Applications Graphics Acceleration Info:");
15775         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15776
15777         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15778             ProcessRecord r = procs.get(i);
15779             if (r.thread != null) {
15780                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15781                 pw.flush();
15782                 try {
15783                     TransferPipe tp = new TransferPipe();
15784                     try {
15785                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15786                         tp.go(fd);
15787                     } finally {
15788                         tp.kill();
15789                     }
15790                 } catch (IOException e) {
15791                     pw.println("Failure while dumping the app: " + r);
15792                     pw.flush();
15793                 } catch (RemoteException e) {
15794                     pw.println("Got a RemoteException while dumping the app " + r);
15795                     pw.flush();
15796                 }
15797             }
15798         }
15799     }
15800
15801     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15802         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15803         if (procs == null) {
15804             pw.println("No process found for: " + args[0]);
15805             return;
15806         }
15807
15808         pw.println("Applications Database Info:");
15809
15810         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15811             ProcessRecord r = procs.get(i);
15812             if (r.thread != null) {
15813                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15814                 pw.flush();
15815                 try {
15816                     TransferPipe tp = new TransferPipe();
15817                     try {
15818                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15819                         tp.go(fd);
15820                     } finally {
15821                         tp.kill();
15822                     }
15823                 } catch (IOException e) {
15824                     pw.println("Failure while dumping the app: " + r);
15825                     pw.flush();
15826                 } catch (RemoteException e) {
15827                     pw.println("Got a RemoteException while dumping the app " + r);
15828                     pw.flush();
15829                 }
15830             }
15831         }
15832     }
15833
15834     final static class MemItem {
15835         final boolean isProc;
15836         final String label;
15837         final String shortLabel;
15838         final long pss;
15839         final long swapPss;
15840         final int id;
15841         final boolean hasActivities;
15842         ArrayList<MemItem> subitems;
15843
15844         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15845                 boolean _hasActivities) {
15846             isProc = true;
15847             label = _label;
15848             shortLabel = _shortLabel;
15849             pss = _pss;
15850             swapPss = _swapPss;
15851             id = _id;
15852             hasActivities = _hasActivities;
15853         }
15854
15855         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15856             isProc = false;
15857             label = _label;
15858             shortLabel = _shortLabel;
15859             pss = _pss;
15860             swapPss = _swapPss;
15861             id = _id;
15862             hasActivities = false;
15863         }
15864     }
15865
15866     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15867             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15868         if (sort && !isCompact) {
15869             Collections.sort(items, new Comparator<MemItem>() {
15870                 @Override
15871                 public int compare(MemItem lhs, MemItem rhs) {
15872                     if (lhs.pss < rhs.pss) {
15873                         return 1;
15874                     } else if (lhs.pss > rhs.pss) {
15875                         return -1;
15876                     }
15877                     return 0;
15878                 }
15879             });
15880         }
15881
15882         for (int i=0; i<items.size(); i++) {
15883             MemItem mi = items.get(i);
15884             if (!isCompact) {
15885                 if (dumpSwapPss) {
15886                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15887                             mi.label, stringifyKBSize(mi.swapPss));
15888                 } else {
15889                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15890                 }
15891             } else if (mi.isProc) {
15892                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15893                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15894                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15895                 pw.println(mi.hasActivities ? ",a" : ",e");
15896             } else {
15897                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15898                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15899             }
15900             if (mi.subitems != null) {
15901                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15902                         true, isCompact, dumpSwapPss);
15903             }
15904         }
15905     }
15906
15907     // These are in KB.
15908     static final long[] DUMP_MEM_BUCKETS = new long[] {
15909         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15910         120*1024, 160*1024, 200*1024,
15911         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15912         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15913     };
15914
15915     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15916             boolean stackLike) {
15917         int start = label.lastIndexOf('.');
15918         if (start >= 0) start++;
15919         else start = 0;
15920         int end = label.length();
15921         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15922             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15923                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15924                 out.append(bucket);
15925                 out.append(stackLike ? "MB." : "MB ");
15926                 out.append(label, start, end);
15927                 return;
15928             }
15929         }
15930         out.append(memKB/1024);
15931         out.append(stackLike ? "MB." : "MB ");
15932         out.append(label, start, end);
15933     }
15934
15935     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15936             ProcessList.NATIVE_ADJ,
15937             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15938             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15939             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15940             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15941             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15942             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15943     };
15944     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15945             "Native",
15946             "System", "Persistent", "Persistent Service", "Foreground",
15947             "Visible", "Perceptible",
15948             "Heavy Weight", "Backup",
15949             "A Services", "Home",
15950             "Previous", "B Services", "Cached"
15951     };
15952     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15953             "native",
15954             "sys", "pers", "persvc", "fore",
15955             "vis", "percept",
15956             "heavy", "backup",
15957             "servicea", "home",
15958             "prev", "serviceb", "cached"
15959     };
15960
15961     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15962             long realtime, boolean isCheckinRequest, boolean isCompact) {
15963         if (isCompact) {
15964             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15965         }
15966         if (isCheckinRequest || isCompact) {
15967             // short checkin version
15968             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15969         } else {
15970             pw.println("Applications Memory Usage (in Kilobytes):");
15971             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15972         }
15973     }
15974
15975     private static final int KSM_SHARED = 0;
15976     private static final int KSM_SHARING = 1;
15977     private static final int KSM_UNSHARED = 2;
15978     private static final int KSM_VOLATILE = 3;
15979
15980     private final long[] getKsmInfo() {
15981         long[] longOut = new long[4];
15982         final int[] SINGLE_LONG_FORMAT = new int[] {
15983             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15984         };
15985         long[] longTmp = new long[1];
15986         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15987                 SINGLE_LONG_FORMAT, null, longTmp, null);
15988         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15989         longTmp[0] = 0;
15990         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15991                 SINGLE_LONG_FORMAT, null, longTmp, null);
15992         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15993         longTmp[0] = 0;
15994         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15995                 SINGLE_LONG_FORMAT, null, longTmp, null);
15996         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15997         longTmp[0] = 0;
15998         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15999                 SINGLE_LONG_FORMAT, null, longTmp, null);
16000         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16001         return longOut;
16002     }
16003
16004     private static String stringifySize(long size, int order) {
16005         Locale locale = Locale.US;
16006         switch (order) {
16007             case 1:
16008                 return String.format(locale, "%,13d", size);
16009             case 1024:
16010                 return String.format(locale, "%,9dK", size / 1024);
16011             case 1024 * 1024:
16012                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16013             case 1024 * 1024 * 1024:
16014                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16015             default:
16016                 throw new IllegalArgumentException("Invalid size order");
16017         }
16018     }
16019
16020     private static String stringifyKBSize(long size) {
16021         return stringifySize(size * 1024, 1024);
16022     }
16023
16024     // Update this version number in case you change the 'compact' format
16025     private static final int MEMINFO_COMPACT_VERSION = 1;
16026
16027     final void dumpApplicationMemoryUsage(FileDescriptor fd,
16028             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16029         boolean dumpDetails = false;
16030         boolean dumpFullDetails = false;
16031         boolean dumpDalvik = false;
16032         boolean dumpSummaryOnly = false;
16033         boolean dumpUnreachable = false;
16034         boolean oomOnly = false;
16035         boolean isCompact = false;
16036         boolean localOnly = false;
16037         boolean packages = false;
16038         boolean isCheckinRequest = false;
16039         boolean dumpSwapPss = false;
16040
16041         int opti = 0;
16042         while (opti < args.length) {
16043             String opt = args[opti];
16044             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16045                 break;
16046             }
16047             opti++;
16048             if ("-a".equals(opt)) {
16049                 dumpDetails = true;
16050                 dumpFullDetails = true;
16051                 dumpDalvik = true;
16052                 dumpSwapPss = true;
16053             } else if ("-d".equals(opt)) {
16054                 dumpDalvik = true;
16055             } else if ("-c".equals(opt)) {
16056                 isCompact = true;
16057             } else if ("-s".equals(opt)) {
16058                 dumpDetails = true;
16059                 dumpSummaryOnly = true;
16060             } else if ("-S".equals(opt)) {
16061                 dumpSwapPss = true;
16062             } else if ("--unreachable".equals(opt)) {
16063                 dumpUnreachable = true;
16064             } else if ("--oom".equals(opt)) {
16065                 oomOnly = true;
16066             } else if ("--local".equals(opt)) {
16067                 localOnly = true;
16068             } else if ("--package".equals(opt)) {
16069                 packages = true;
16070             } else if ("--checkin".equals(opt)) {
16071                 isCheckinRequest = true;
16072
16073             } else if ("-h".equals(opt)) {
16074                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16075                 pw.println("  -a: include all available information for each process.");
16076                 pw.println("  -d: include dalvik details.");
16077                 pw.println("  -c: dump in a compact machine-parseable representation.");
16078                 pw.println("  -s: dump only summary of application memory usage.");
16079                 pw.println("  -S: dump also SwapPss.");
16080                 pw.println("  --oom: only show processes organized by oom adj.");
16081                 pw.println("  --local: only collect details locally, don't call process.");
16082                 pw.println("  --package: interpret process arg as package, dumping all");
16083                 pw.println("             processes that have loaded that package.");
16084                 pw.println("  --checkin: dump data for a checkin");
16085                 pw.println("If [process] is specified it can be the name or ");
16086                 pw.println("pid of a specific process to dump.");
16087                 return;
16088             } else {
16089                 pw.println("Unknown argument: " + opt + "; use -h for help");
16090             }
16091         }
16092
16093         long uptime = SystemClock.uptimeMillis();
16094         long realtime = SystemClock.elapsedRealtime();
16095         final long[] tmpLong = new long[1];
16096
16097         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16098         if (procs == null) {
16099             // No Java processes.  Maybe they want to print a native process.
16100             if (args != null && args.length > opti
16101                     && args[opti].charAt(0) != '-') {
16102                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16103                         = new ArrayList<ProcessCpuTracker.Stats>();
16104                 updateCpuStatsNow();
16105                 int findPid = -1;
16106                 try {
16107                     findPid = Integer.parseInt(args[opti]);
16108                 } catch (NumberFormatException e) {
16109                 }
16110                 synchronized (mProcessCpuTracker) {
16111                     final int N = mProcessCpuTracker.countStats();
16112                     for (int i=0; i<N; i++) {
16113                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16114                         if (st.pid == findPid || (st.baseName != null
16115                                 && st.baseName.equals(args[opti]))) {
16116                             nativeProcs.add(st);
16117                         }
16118                     }
16119                 }
16120                 if (nativeProcs.size() > 0) {
16121                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16122                             isCompact);
16123                     Debug.MemoryInfo mi = null;
16124                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16125                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16126                         final int pid = r.pid;
16127                         if (!isCheckinRequest && dumpDetails) {
16128                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16129                         }
16130                         if (mi == null) {
16131                             mi = new Debug.MemoryInfo();
16132                         }
16133                         if (dumpDetails || (!brief && !oomOnly)) {
16134                             Debug.getMemoryInfo(pid, mi);
16135                         } else {
16136                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16137                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16138                         }
16139                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16140                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16141                         if (isCheckinRequest) {
16142                             pw.println();
16143                         }
16144                     }
16145                     return;
16146                 }
16147             }
16148             pw.println("No process found for: " + args[opti]);
16149             return;
16150         }
16151
16152         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16153             dumpDetails = true;
16154         }
16155
16156         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16157
16158         String[] innerArgs = new String[args.length-opti];
16159         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16160
16161         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16162         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16163         long nativePss = 0;
16164         long nativeSwapPss = 0;
16165         long dalvikPss = 0;
16166         long dalvikSwapPss = 0;
16167         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16168                 EmptyArray.LONG;
16169         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16170                 EmptyArray.LONG;
16171         long otherPss = 0;
16172         long otherSwapPss = 0;
16173         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16174         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16175
16176         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16177         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16178         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16179                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16180
16181         long totalPss = 0;
16182         long totalSwapPss = 0;
16183         long cachedPss = 0;
16184         long cachedSwapPss = 0;
16185         boolean hasSwapPss = false;
16186
16187         Debug.MemoryInfo mi = null;
16188         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16189             final ProcessRecord r = procs.get(i);
16190             final IApplicationThread thread;
16191             final int pid;
16192             final int oomAdj;
16193             final boolean hasActivities;
16194             synchronized (this) {
16195                 thread = r.thread;
16196                 pid = r.pid;
16197                 oomAdj = r.getSetAdjWithServices();
16198                 hasActivities = r.activities.size() > 0;
16199             }
16200             if (thread != null) {
16201                 if (!isCheckinRequest && dumpDetails) {
16202                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16203                 }
16204                 if (mi == null) {
16205                     mi = new Debug.MemoryInfo();
16206                 }
16207                 if (dumpDetails || (!brief && !oomOnly)) {
16208                     Debug.getMemoryInfo(pid, mi);
16209                     hasSwapPss = mi.hasSwappedOutPss;
16210                 } else {
16211                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16212                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16213                 }
16214                 if (dumpDetails) {
16215                     if (localOnly) {
16216                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16217                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16218                         if (isCheckinRequest) {
16219                             pw.println();
16220                         }
16221                     } else {
16222                         try {
16223                             pw.flush();
16224                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16225                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16226                         } catch (RemoteException e) {
16227                             if (!isCheckinRequest) {
16228                                 pw.println("Got RemoteException!");
16229                                 pw.flush();
16230                             }
16231                         }
16232                     }
16233                 }
16234
16235                 final long myTotalPss = mi.getTotalPss();
16236                 final long myTotalUss = mi.getTotalUss();
16237                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16238
16239                 synchronized (this) {
16240                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16241                         // Record this for posterity if the process has been stable.
16242                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16243                     }
16244                 }
16245
16246                 if (!isCheckinRequest && mi != null) {
16247                     totalPss += myTotalPss;
16248                     totalSwapPss += myTotalSwapPss;
16249                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16250                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16251                             myTotalSwapPss, pid, hasActivities);
16252                     procMems.add(pssItem);
16253                     procMemsMap.put(pid, pssItem);
16254
16255                     nativePss += mi.nativePss;
16256                     nativeSwapPss += mi.nativeSwappedOutPss;
16257                     dalvikPss += mi.dalvikPss;
16258                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16259                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16260                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16261                         dalvikSubitemSwapPss[j] +=
16262                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16263                     }
16264                     otherPss += mi.otherPss;
16265                     otherSwapPss += mi.otherSwappedOutPss;
16266                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16267                         long mem = mi.getOtherPss(j);
16268                         miscPss[j] += mem;
16269                         otherPss -= mem;
16270                         mem = mi.getOtherSwappedOutPss(j);
16271                         miscSwapPss[j] += mem;
16272                         otherSwapPss -= mem;
16273                     }
16274
16275                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16276                         cachedPss += myTotalPss;
16277                         cachedSwapPss += myTotalSwapPss;
16278                     }
16279
16280                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16281                         if (oomIndex == (oomPss.length - 1)
16282                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16283                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16284                             oomPss[oomIndex] += myTotalPss;
16285                             oomSwapPss[oomIndex] += myTotalSwapPss;
16286                             if (oomProcs[oomIndex] == null) {
16287                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16288                             }
16289                             oomProcs[oomIndex].add(pssItem);
16290                             break;
16291                         }
16292                     }
16293                 }
16294             }
16295         }
16296
16297         long nativeProcTotalPss = 0;
16298
16299         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16300             // If we are showing aggregations, also look for native processes to
16301             // include so that our aggregations are more accurate.
16302             updateCpuStatsNow();
16303             mi = null;
16304             synchronized (mProcessCpuTracker) {
16305                 final int N = mProcessCpuTracker.countStats();
16306                 for (int i=0; i<N; i++) {
16307                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16308                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16309                         if (mi == null) {
16310                             mi = new Debug.MemoryInfo();
16311                         }
16312                         if (!brief && !oomOnly) {
16313                             Debug.getMemoryInfo(st.pid, mi);
16314                         } else {
16315                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16316                             mi.nativePrivateDirty = (int)tmpLong[0];
16317                         }
16318
16319                         final long myTotalPss = mi.getTotalPss();
16320                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16321                         totalPss += myTotalPss;
16322                         nativeProcTotalPss += myTotalPss;
16323
16324                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16325                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16326                         procMems.add(pssItem);
16327
16328                         nativePss += mi.nativePss;
16329                         nativeSwapPss += mi.nativeSwappedOutPss;
16330                         dalvikPss += mi.dalvikPss;
16331                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16332                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16333                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16334                             dalvikSubitemSwapPss[j] +=
16335                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16336                         }
16337                         otherPss += mi.otherPss;
16338                         otherSwapPss += mi.otherSwappedOutPss;
16339                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16340                             long mem = mi.getOtherPss(j);
16341                             miscPss[j] += mem;
16342                             otherPss -= mem;
16343                             mem = mi.getOtherSwappedOutPss(j);
16344                             miscSwapPss[j] += mem;
16345                             otherSwapPss -= mem;
16346                         }
16347                         oomPss[0] += myTotalPss;
16348                         oomSwapPss[0] += myTotalSwapPss;
16349                         if (oomProcs[0] == null) {
16350                             oomProcs[0] = new ArrayList<MemItem>();
16351                         }
16352                         oomProcs[0].add(pssItem);
16353                     }
16354                 }
16355             }
16356
16357             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16358
16359             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16360             final MemItem dalvikItem =
16361                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16362             if (dalvikSubitemPss.length > 0) {
16363                 dalvikItem.subitems = new ArrayList<MemItem>();
16364                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16365                     final String name = Debug.MemoryInfo.getOtherLabel(
16366                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16367                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16368                                     dalvikSubitemSwapPss[j], j));
16369                 }
16370             }
16371             catMems.add(dalvikItem);
16372             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16373             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16374                 String label = Debug.MemoryInfo.getOtherLabel(j);
16375                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16376             }
16377
16378             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16379             for (int j=0; j<oomPss.length; j++) {
16380                 if (oomPss[j] != 0) {
16381                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16382                             : DUMP_MEM_OOM_LABEL[j];
16383                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16384                             DUMP_MEM_OOM_ADJ[j]);
16385                     item.subitems = oomProcs[j];
16386                     oomMems.add(item);
16387                 }
16388             }
16389
16390             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16391             if (!brief && !oomOnly && !isCompact) {
16392                 pw.println();
16393                 pw.println("Total PSS by process:");
16394                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16395                 pw.println();
16396             }
16397             if (!isCompact) {
16398                 pw.println("Total PSS by OOM adjustment:");
16399             }
16400             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16401             if (!brief && !oomOnly) {
16402                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16403                 if (!isCompact) {
16404                     out.println();
16405                     out.println("Total PSS by category:");
16406                 }
16407                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16408             }
16409             if (!isCompact) {
16410                 pw.println();
16411             }
16412             MemInfoReader memInfo = new MemInfoReader();
16413             memInfo.readMemInfo();
16414             if (nativeProcTotalPss > 0) {
16415                 synchronized (this) {
16416                     final long cachedKb = memInfo.getCachedSizeKb();
16417                     final long freeKb = memInfo.getFreeSizeKb();
16418                     final long zramKb = memInfo.getZramTotalSizeKb();
16419                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16420                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16421                             kernelKb*1024, nativeProcTotalPss*1024);
16422                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16423                             nativeProcTotalPss);
16424                 }
16425             }
16426             if (!brief) {
16427                 if (!isCompact) {
16428                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16429                     pw.print(" (status ");
16430                     switch (mLastMemoryLevel) {
16431                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16432                             pw.println("normal)");
16433                             break;
16434                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16435                             pw.println("moderate)");
16436                             break;
16437                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16438                             pw.println("low)");
16439                             break;
16440                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16441                             pw.println("critical)");
16442                             break;
16443                         default:
16444                             pw.print(mLastMemoryLevel);
16445                             pw.println(")");
16446                             break;
16447                     }
16448                     pw.print(" Free RAM: ");
16449                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16450                             + memInfo.getFreeSizeKb()));
16451                     pw.print(" (");
16452                     pw.print(stringifyKBSize(cachedPss));
16453                     pw.print(" cached pss + ");
16454                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16455                     pw.print(" cached kernel + ");
16456                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16457                     pw.println(" free)");
16458                 } else {
16459                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16460                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16461                             + memInfo.getFreeSizeKb()); pw.print(",");
16462                     pw.println(totalPss - cachedPss);
16463                 }
16464             }
16465             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16466                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16467                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16468             if (!isCompact) {
16469                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16470                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16471                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16472                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16473                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16474             } else {
16475                 pw.print("lostram,"); pw.println(lostRAM);
16476             }
16477             if (!brief) {
16478                 if (memInfo.getZramTotalSizeKb() != 0) {
16479                     if (!isCompact) {
16480                         pw.print("     ZRAM: ");
16481                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16482                                 pw.print(" physical used for ");
16483                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16484                                         - memInfo.getSwapFreeSizeKb()));
16485                                 pw.print(" in swap (");
16486                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16487                                 pw.println(" total swap)");
16488                     } else {
16489                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16490                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16491                                 pw.println(memInfo.getSwapFreeSizeKb());
16492                     }
16493                 }
16494                 final long[] ksm = getKsmInfo();
16495                 if (!isCompact) {
16496                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16497                             || ksm[KSM_VOLATILE] != 0) {
16498                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16499                                 pw.print(" saved from shared ");
16500                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16501                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16502                                 pw.print(" unshared; ");
16503                                 pw.print(stringifyKBSize(
16504                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16505                     }
16506                     pw.print("   Tuning: ");
16507                     pw.print(ActivityManager.staticGetMemoryClass());
16508                     pw.print(" (large ");
16509                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16510                     pw.print("), oom ");
16511                     pw.print(stringifySize(
16512                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16513                     pw.print(", restore limit ");
16514                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16515                     if (ActivityManager.isLowRamDeviceStatic()) {
16516                         pw.print(" (low-ram)");
16517                     }
16518                     if (ActivityManager.isHighEndGfx()) {
16519                         pw.print(" (high-end-gfx)");
16520                     }
16521                     pw.println();
16522                 } else {
16523                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16524                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16525                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16526                     pw.print("tuning,");
16527                     pw.print(ActivityManager.staticGetMemoryClass());
16528                     pw.print(',');
16529                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16530                     pw.print(',');
16531                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16532                     if (ActivityManager.isLowRamDeviceStatic()) {
16533                         pw.print(",low-ram");
16534                     }
16535                     if (ActivityManager.isHighEndGfx()) {
16536                         pw.print(",high-end-gfx");
16537                     }
16538                     pw.println();
16539                 }
16540             }
16541         }
16542     }
16543
16544     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16545             long memtrack, String name) {
16546         sb.append("  ");
16547         sb.append(ProcessList.makeOomAdjString(oomAdj));
16548         sb.append(' ');
16549         sb.append(ProcessList.makeProcStateString(procState));
16550         sb.append(' ');
16551         ProcessList.appendRamKb(sb, pss);
16552         sb.append(": ");
16553         sb.append(name);
16554         if (memtrack > 0) {
16555             sb.append(" (");
16556             sb.append(stringifyKBSize(memtrack));
16557             sb.append(" memtrack)");
16558         }
16559     }
16560
16561     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16562         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16563         sb.append(" (pid ");
16564         sb.append(mi.pid);
16565         sb.append(") ");
16566         sb.append(mi.adjType);
16567         sb.append('\n');
16568         if (mi.adjReason != null) {
16569             sb.append("                      ");
16570             sb.append(mi.adjReason);
16571             sb.append('\n');
16572         }
16573     }
16574
16575     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16576         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16577         for (int i=0, N=memInfos.size(); i<N; i++) {
16578             ProcessMemInfo mi = memInfos.get(i);
16579             infoMap.put(mi.pid, mi);
16580         }
16581         updateCpuStatsNow();
16582         long[] memtrackTmp = new long[1];
16583         synchronized (mProcessCpuTracker) {
16584             final int N = mProcessCpuTracker.countStats();
16585             for (int i=0; i<N; i++) {
16586                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16587                 if (st.vsize > 0) {
16588                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
16589                     if (pss > 0) {
16590                         if (infoMap.indexOfKey(st.pid) < 0) {
16591                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16592                                     ProcessList.NATIVE_ADJ, -1, "native", null);
16593                             mi.pss = pss;
16594                             mi.memtrack = memtrackTmp[0];
16595                             memInfos.add(mi);
16596                         }
16597                     }
16598                 }
16599             }
16600         }
16601
16602         long totalPss = 0;
16603         long totalMemtrack = 0;
16604         for (int i=0, N=memInfos.size(); i<N; i++) {
16605             ProcessMemInfo mi = memInfos.get(i);
16606             if (mi.pss == 0) {
16607                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16608                 mi.memtrack = memtrackTmp[0];
16609             }
16610             totalPss += mi.pss;
16611             totalMemtrack += mi.memtrack;
16612         }
16613         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16614             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16615                 if (lhs.oomAdj != rhs.oomAdj) {
16616                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16617                 }
16618                 if (lhs.pss != rhs.pss) {
16619                     return lhs.pss < rhs.pss ? 1 : -1;
16620                 }
16621                 return 0;
16622             }
16623         });
16624
16625         StringBuilder tag = new StringBuilder(128);
16626         StringBuilder stack = new StringBuilder(128);
16627         tag.append("Low on memory -- ");
16628         appendMemBucket(tag, totalPss, "total", false);
16629         appendMemBucket(stack, totalPss, "total", true);
16630
16631         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16632         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16633         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16634
16635         boolean firstLine = true;
16636         int lastOomAdj = Integer.MIN_VALUE;
16637         long extraNativeRam = 0;
16638         long extraNativeMemtrack = 0;
16639         long cachedPss = 0;
16640         for (int i=0, N=memInfos.size(); i<N; i++) {
16641             ProcessMemInfo mi = memInfos.get(i);
16642
16643             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16644                 cachedPss += mi.pss;
16645             }
16646
16647             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16648                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16649                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16650                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16651                 if (lastOomAdj != mi.oomAdj) {
16652                     lastOomAdj = mi.oomAdj;
16653                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16654                         tag.append(" / ");
16655                     }
16656                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16657                         if (firstLine) {
16658                             stack.append(":");
16659                             firstLine = false;
16660                         }
16661                         stack.append("\n\t at ");
16662                     } else {
16663                         stack.append("$");
16664                     }
16665                 } else {
16666                     tag.append(" ");
16667                     stack.append("$");
16668                 }
16669                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16670                     appendMemBucket(tag, mi.pss, mi.name, false);
16671                 }
16672                 appendMemBucket(stack, mi.pss, mi.name, true);
16673                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16674                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16675                     stack.append("(");
16676                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16677                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16678                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16679                             stack.append(":");
16680                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16681                         }
16682                     }
16683                     stack.append(")");
16684                 }
16685             }
16686
16687             appendMemInfo(fullNativeBuilder, mi);
16688             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16689                 // The short form only has native processes that are >= 512K.
16690                 if (mi.pss >= 512) {
16691                     appendMemInfo(shortNativeBuilder, mi);
16692                 } else {
16693                     extraNativeRam += mi.pss;
16694                     extraNativeMemtrack += mi.memtrack;
16695                 }
16696             } else {
16697                 // Short form has all other details, but if we have collected RAM
16698                 // from smaller native processes let's dump a summary of that.
16699                 if (extraNativeRam > 0) {
16700                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16701                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16702                     shortNativeBuilder.append('\n');
16703                     extraNativeRam = 0;
16704                 }
16705                 appendMemInfo(fullJavaBuilder, mi);
16706             }
16707         }
16708
16709         fullJavaBuilder.append("           ");
16710         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16711         fullJavaBuilder.append(": TOTAL");
16712         if (totalMemtrack > 0) {
16713             fullJavaBuilder.append(" (");
16714             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16715             fullJavaBuilder.append(" memtrack)");
16716         } else {
16717         }
16718         fullJavaBuilder.append("\n");
16719
16720         MemInfoReader memInfo = new MemInfoReader();
16721         memInfo.readMemInfo();
16722         final long[] infos = memInfo.getRawInfo();
16723
16724         StringBuilder memInfoBuilder = new StringBuilder(1024);
16725         Debug.getMemInfo(infos);
16726         memInfoBuilder.append("  MemInfo: ");
16727         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16728         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16729         memInfoBuilder.append(stringifyKBSize(
16730                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16731         memInfoBuilder.append(stringifyKBSize(
16732                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16733         memInfoBuilder.append(stringifyKBSize(
16734                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16735         memInfoBuilder.append("           ");
16736         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16737         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16738         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16739         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16740         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16741             memInfoBuilder.append("  ZRAM: ");
16742             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16743             memInfoBuilder.append(" RAM, ");
16744             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16745             memInfoBuilder.append(" swap total, ");
16746             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16747             memInfoBuilder.append(" swap free\n");
16748         }
16749         final long[] ksm = getKsmInfo();
16750         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16751                 || ksm[KSM_VOLATILE] != 0) {
16752             memInfoBuilder.append("  KSM: ");
16753             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16754             memInfoBuilder.append(" saved from shared ");
16755             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16756             memInfoBuilder.append("\n       ");
16757             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16758             memInfoBuilder.append(" unshared; ");
16759             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16760             memInfoBuilder.append(" volatile\n");
16761         }
16762         memInfoBuilder.append("  Free RAM: ");
16763         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16764                 + memInfo.getFreeSizeKb()));
16765         memInfoBuilder.append("\n");
16766         memInfoBuilder.append("  Used RAM: ");
16767         memInfoBuilder.append(stringifyKBSize(
16768                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16769         memInfoBuilder.append("\n");
16770         memInfoBuilder.append("  Lost RAM: ");
16771         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16772                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16773                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16774         memInfoBuilder.append("\n");
16775         Slog.i(TAG, "Low on memory:");
16776         Slog.i(TAG, shortNativeBuilder.toString());
16777         Slog.i(TAG, fullJavaBuilder.toString());
16778         Slog.i(TAG, memInfoBuilder.toString());
16779
16780         StringBuilder dropBuilder = new StringBuilder(1024);
16781         /*
16782         StringWriter oomSw = new StringWriter();
16783         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16784         StringWriter catSw = new StringWriter();
16785         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16786         String[] emptyArgs = new String[] { };
16787         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16788         oomPw.flush();
16789         String oomString = oomSw.toString();
16790         */
16791         dropBuilder.append("Low on memory:");
16792         dropBuilder.append(stack);
16793         dropBuilder.append('\n');
16794         dropBuilder.append(fullNativeBuilder);
16795         dropBuilder.append(fullJavaBuilder);
16796         dropBuilder.append('\n');
16797         dropBuilder.append(memInfoBuilder);
16798         dropBuilder.append('\n');
16799         /*
16800         dropBuilder.append(oomString);
16801         dropBuilder.append('\n');
16802         */
16803         StringWriter catSw = new StringWriter();
16804         synchronized (ActivityManagerService.this) {
16805             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16806             String[] emptyArgs = new String[] { };
16807             catPw.println();
16808             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16809             catPw.println();
16810             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16811                     false, null).dumpLocked();
16812             catPw.println();
16813             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16814             catPw.flush();
16815         }
16816         dropBuilder.append(catSw.toString());
16817         addErrorToDropBox("lowmem", null, "system_server", null,
16818                 null, tag.toString(), dropBuilder.toString(), null, null);
16819         //Slog.i(TAG, "Sent to dropbox:");
16820         //Slog.i(TAG, dropBuilder.toString());
16821         synchronized (ActivityManagerService.this) {
16822             long now = SystemClock.uptimeMillis();
16823             if (mLastMemUsageReportTime < now) {
16824                 mLastMemUsageReportTime = now;
16825             }
16826         }
16827     }
16828
16829     /**
16830      * Searches array of arguments for the specified string
16831      * @param args array of argument strings
16832      * @param value value to search for
16833      * @return true if the value is contained in the array
16834      */
16835     private static boolean scanArgs(String[] args, String value) {
16836         if (args != null) {
16837             for (String arg : args) {
16838                 if (value.equals(arg)) {
16839                     return true;
16840                 }
16841             }
16842         }
16843         return false;
16844     }
16845
16846     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16847             ContentProviderRecord cpr, boolean always) {
16848         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16849
16850         if (!inLaunching || always) {
16851             synchronized (cpr) {
16852                 cpr.launchingApp = null;
16853                 cpr.notifyAll();
16854             }
16855             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16856             String names[] = cpr.info.authority.split(";");
16857             for (int j = 0; j < names.length; j++) {
16858                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16859             }
16860         }
16861
16862         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16863             ContentProviderConnection conn = cpr.connections.get(i);
16864             if (conn.waiting) {
16865                 // If this connection is waiting for the provider, then we don't
16866                 // need to mess with its process unless we are always removing
16867                 // or for some reason the provider is not currently launching.
16868                 if (inLaunching && !always) {
16869                     continue;
16870                 }
16871             }
16872             ProcessRecord capp = conn.client;
16873             conn.dead = true;
16874             if (conn.stableCount > 0) {
16875                 if (!capp.persistent && capp.thread != null
16876                         && capp.pid != 0
16877                         && capp.pid != MY_PID) {
16878                     capp.kill("depends on provider "
16879                             + cpr.name.flattenToShortString()
16880                             + " in dying proc " + (proc != null ? proc.processName : "??")
16881                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16882                 }
16883             } else if (capp.thread != null && conn.provider.provider != null) {
16884                 try {
16885                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16886                 } catch (RemoteException e) {
16887                 }
16888                 // In the protocol here, we don't expect the client to correctly
16889                 // clean up this connection, we'll just remove it.
16890                 cpr.connections.remove(i);
16891                 if (conn.client.conProviders.remove(conn)) {
16892                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16893                 }
16894             }
16895         }
16896
16897         if (inLaunching && always) {
16898             mLaunchingProviders.remove(cpr);
16899         }
16900         return inLaunching;
16901     }
16902
16903     /**
16904      * Main code for cleaning up a process when it has gone away.  This is
16905      * called both as a result of the process dying, or directly when stopping
16906      * a process when running in single process mode.
16907      *
16908      * @return Returns true if the given process has been restarted, so the
16909      * app that was passed in must remain on the process lists.
16910      */
16911     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16912             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16913         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16914         if (index >= 0) {
16915             removeLruProcessLocked(app);
16916             ProcessList.remove(app.pid);
16917         }
16918
16919         mProcessesToGc.remove(app);
16920         mPendingPssProcesses.remove(app);
16921
16922         // Dismiss any open dialogs.
16923         if (app.crashDialog != null && !app.forceCrashReport) {
16924             app.crashDialog.dismiss();
16925             app.crashDialog = null;
16926         }
16927         if (app.anrDialog != null) {
16928             app.anrDialog.dismiss();
16929             app.anrDialog = null;
16930         }
16931         if (app.waitDialog != null) {
16932             app.waitDialog.dismiss();
16933             app.waitDialog = null;
16934         }
16935
16936         app.crashing = false;
16937         app.notResponding = false;
16938
16939         app.resetPackageList(mProcessStats);
16940         app.unlinkDeathRecipient();
16941         app.makeInactive(mProcessStats);
16942         app.waitingToKill = null;
16943         app.forcingToForeground = null;
16944         updateProcessForegroundLocked(app, false, false);
16945         app.foregroundActivities = false;
16946         app.hasShownUi = false;
16947         app.treatLikeActivity = false;
16948         app.hasAboveClient = false;
16949         app.hasClientActivities = false;
16950
16951         mServices.killServicesLocked(app, allowRestart);
16952
16953         boolean restart = false;
16954
16955         // Remove published content providers.
16956         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16957             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16958             final boolean always = app.bad || !allowRestart;
16959             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16960             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16961                 // We left the provider in the launching list, need to
16962                 // restart it.
16963                 restart = true;
16964             }
16965
16966             cpr.provider = null;
16967             cpr.proc = null;
16968         }
16969         app.pubProviders.clear();
16970
16971         // Take care of any launching providers waiting for this process.
16972         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16973             restart = true;
16974         }
16975
16976         // Unregister from connected content providers.
16977         if (!app.conProviders.isEmpty()) {
16978             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16979                 ContentProviderConnection conn = app.conProviders.get(i);
16980                 conn.provider.connections.remove(conn);
16981                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16982                         conn.provider.name);
16983             }
16984             app.conProviders.clear();
16985         }
16986
16987         // At this point there may be remaining entries in mLaunchingProviders
16988         // where we were the only one waiting, so they are no longer of use.
16989         // Look for these and clean up if found.
16990         // XXX Commented out for now.  Trying to figure out a way to reproduce
16991         // the actual situation to identify what is actually going on.
16992         if (false) {
16993             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16994                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16995                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16996                     synchronized (cpr) {
16997                         cpr.launchingApp = null;
16998                         cpr.notifyAll();
16999                     }
17000                 }
17001             }
17002         }
17003
17004         skipCurrentReceiverLocked(app);
17005
17006         // Unregister any receivers.
17007         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17008             removeReceiverLocked(app.receivers.valueAt(i));
17009         }
17010         app.receivers.clear();
17011
17012         // If the app is undergoing backup, tell the backup manager about it
17013         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17014             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17015                     + mBackupTarget.appInfo + " died during backup");
17016             try {
17017                 IBackupManager bm = IBackupManager.Stub.asInterface(
17018                         ServiceManager.getService(Context.BACKUP_SERVICE));
17019                 bm.agentDisconnected(app.info.packageName);
17020             } catch (RemoteException e) {
17021                 // can't happen; backup manager is local
17022             }
17023         }
17024
17025         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17026             ProcessChangeItem item = mPendingProcessChanges.get(i);
17027             if (item.pid == app.pid) {
17028                 mPendingProcessChanges.remove(i);
17029                 mAvailProcessChanges.add(item);
17030             }
17031         }
17032         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17033                 null).sendToTarget();
17034
17035         // If the caller is restarting this app, then leave it in its
17036         // current lists and let the caller take care of it.
17037         if (restarting) {
17038             return false;
17039         }
17040
17041         if (!app.persistent || app.isolated) {
17042             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17043                     "Removing non-persistent process during cleanup: " + app);
17044             if (!replacingPid) {
17045                 removeProcessNameLocked(app.processName, app.uid);
17046             }
17047             if (mHeavyWeightProcess == app) {
17048                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17049                         mHeavyWeightProcess.userId, 0));
17050                 mHeavyWeightProcess = null;
17051             }
17052         } else if (!app.removed) {
17053             // This app is persistent, so we need to keep its record around.
17054             // If it is not already on the pending app list, add it there
17055             // and start a new process for it.
17056             if (mPersistentStartingProcesses.indexOf(app) < 0) {
17057                 mPersistentStartingProcesses.add(app);
17058                 restart = true;
17059             }
17060         }
17061         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17062                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17063         mProcessesOnHold.remove(app);
17064
17065         if (app == mHomeProcess) {
17066             mHomeProcess = null;
17067         }
17068         if (app == mPreviousProcess) {
17069             mPreviousProcess = null;
17070         }
17071
17072         if (restart && !app.isolated) {
17073             // We have components that still need to be running in the
17074             // process, so re-launch it.
17075             if (index < 0) {
17076                 ProcessList.remove(app.pid);
17077             }
17078             addProcessNameLocked(app);
17079             startProcessLocked(app, "restart", app.processName);
17080             return true;
17081         } else if (app.pid > 0 && app.pid != MY_PID) {
17082             // Goodbye!
17083             boolean removed;
17084             synchronized (mPidsSelfLocked) {
17085                 mPidsSelfLocked.remove(app.pid);
17086                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17087             }
17088             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17089             if (app.isolated) {
17090                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17091             }
17092             app.setPid(0);
17093         }
17094         return false;
17095     }
17096
17097     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17098         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17099             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17100             if (cpr.launchingApp == app) {
17101                 return true;
17102             }
17103         }
17104         return false;
17105     }
17106
17107     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17108         // Look through the content providers we are waiting to have launched,
17109         // and if any run in this process then either schedule a restart of
17110         // the process or kill the client waiting for it if this process has
17111         // gone bad.
17112         boolean restart = false;
17113         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17114             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17115             if (cpr.launchingApp == app) {
17116                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17117                     restart = true;
17118                 } else {
17119                     removeDyingProviderLocked(app, cpr, true);
17120                 }
17121             }
17122         }
17123         return restart;
17124     }
17125
17126     // =========================================================
17127     // SERVICES
17128     // =========================================================
17129
17130     @Override
17131     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17132             int flags) {
17133         enforceNotIsolatedCaller("getServices");
17134         synchronized (this) {
17135             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17136         }
17137     }
17138
17139     @Override
17140     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17141         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17142         synchronized (this) {
17143             return mServices.getRunningServiceControlPanelLocked(name);
17144         }
17145     }
17146
17147     @Override
17148     public ComponentName startService(IApplicationThread caller, Intent service,
17149             String resolvedType, String callingPackage, int userId)
17150             throws TransactionTooLargeException {
17151         enforceNotIsolatedCaller("startService");
17152         // Refuse possible leaked file descriptors
17153         if (service != null && service.hasFileDescriptors() == true) {
17154             throw new IllegalArgumentException("File descriptors passed in Intent");
17155         }
17156
17157         if (callingPackage == null) {
17158             throw new IllegalArgumentException("callingPackage cannot be null");
17159         }
17160
17161         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17162                 "startService: " + service + " type=" + resolvedType);
17163         synchronized(this) {
17164             final int callingPid = Binder.getCallingPid();
17165             final int callingUid = Binder.getCallingUid();
17166             final long origId = Binder.clearCallingIdentity();
17167             ComponentName res = mServices.startServiceLocked(caller, service,
17168                     resolvedType, callingPid, callingUid, callingPackage, userId);
17169             Binder.restoreCallingIdentity(origId);
17170             return res;
17171         }
17172     }
17173
17174     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17175             String callingPackage, int userId)
17176             throws TransactionTooLargeException {
17177         synchronized(this) {
17178             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17179                     "startServiceInPackage: " + service + " type=" + resolvedType);
17180             final long origId = Binder.clearCallingIdentity();
17181             ComponentName res = mServices.startServiceLocked(null, service,
17182                     resolvedType, -1, uid, callingPackage, userId);
17183             Binder.restoreCallingIdentity(origId);
17184             return res;
17185         }
17186     }
17187
17188     @Override
17189     public int stopService(IApplicationThread caller, Intent service,
17190             String resolvedType, int userId) {
17191         enforceNotIsolatedCaller("stopService");
17192         // Refuse possible leaked file descriptors
17193         if (service != null && service.hasFileDescriptors() == true) {
17194             throw new IllegalArgumentException("File descriptors passed in Intent");
17195         }
17196
17197         synchronized(this) {
17198             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17199         }
17200     }
17201
17202     @Override
17203     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17204         enforceNotIsolatedCaller("peekService");
17205         // Refuse possible leaked file descriptors
17206         if (service != null && service.hasFileDescriptors() == true) {
17207             throw new IllegalArgumentException("File descriptors passed in Intent");
17208         }
17209
17210         if (callingPackage == null) {
17211             throw new IllegalArgumentException("callingPackage cannot be null");
17212         }
17213
17214         synchronized(this) {
17215             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17216         }
17217     }
17218
17219     @Override
17220     public boolean stopServiceToken(ComponentName className, IBinder token,
17221             int startId) {
17222         synchronized(this) {
17223             return mServices.stopServiceTokenLocked(className, token, startId);
17224         }
17225     }
17226
17227     @Override
17228     public void setServiceForeground(ComponentName className, IBinder token,
17229             int id, Notification notification, int flags) {
17230         synchronized(this) {
17231             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17232         }
17233     }
17234
17235     @Override
17236     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17237             boolean requireFull, String name, String callerPackage) {
17238         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17239                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17240     }
17241
17242     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17243             String className, int flags) {
17244         boolean result = false;
17245         // For apps that don't have pre-defined UIDs, check for permission
17246         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17247             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17248                 if (ActivityManager.checkUidPermission(
17249                         INTERACT_ACROSS_USERS,
17250                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17251                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17252                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17253                             + " requests FLAG_SINGLE_USER, but app does not hold "
17254                             + INTERACT_ACROSS_USERS;
17255                     Slog.w(TAG, msg);
17256                     throw new SecurityException(msg);
17257                 }
17258                 // Permission passed
17259                 result = true;
17260             }
17261         } else if ("system".equals(componentProcessName)) {
17262             result = true;
17263         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17264             // Phone app and persistent apps are allowed to export singleuser providers.
17265             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17266                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17267         }
17268         if (DEBUG_MU) Slog.v(TAG_MU,
17269                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17270                 + Integer.toHexString(flags) + ") = " + result);
17271         return result;
17272     }
17273
17274     /**
17275      * Checks to see if the caller is in the same app as the singleton
17276      * component, or the component is in a special app. It allows special apps
17277      * to export singleton components but prevents exporting singleton
17278      * components for regular apps.
17279      */
17280     boolean isValidSingletonCall(int callingUid, int componentUid) {
17281         int componentAppId = UserHandle.getAppId(componentUid);
17282         return UserHandle.isSameApp(callingUid, componentUid)
17283                 || componentAppId == Process.SYSTEM_UID
17284                 || componentAppId == Process.PHONE_UID
17285                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17286                         == PackageManager.PERMISSION_GRANTED;
17287     }
17288
17289     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17290             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17291             int userId) throws TransactionTooLargeException {
17292         enforceNotIsolatedCaller("bindService");
17293
17294         // Refuse possible leaked file descriptors
17295         if (service != null && service.hasFileDescriptors() == true) {
17296             throw new IllegalArgumentException("File descriptors passed in Intent");
17297         }
17298
17299         if (callingPackage == null) {
17300             throw new IllegalArgumentException("callingPackage cannot be null");
17301         }
17302
17303         synchronized(this) {
17304             return mServices.bindServiceLocked(caller, token, service,
17305                     resolvedType, connection, flags, callingPackage, userId);
17306         }
17307     }
17308
17309     public boolean unbindService(IServiceConnection connection) {
17310         synchronized (this) {
17311             return mServices.unbindServiceLocked(connection);
17312         }
17313     }
17314
17315     public void publishService(IBinder token, Intent intent, IBinder service) {
17316         // Refuse possible leaked file descriptors
17317         if (intent != null && intent.hasFileDescriptors() == true) {
17318             throw new IllegalArgumentException("File descriptors passed in Intent");
17319         }
17320
17321         synchronized(this) {
17322             if (!(token instanceof ServiceRecord)) {
17323                 throw new IllegalArgumentException("Invalid service token");
17324             }
17325             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17326         }
17327     }
17328
17329     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17330         // Refuse possible leaked file descriptors
17331         if (intent != null && intent.hasFileDescriptors() == true) {
17332             throw new IllegalArgumentException("File descriptors passed in Intent");
17333         }
17334
17335         synchronized(this) {
17336             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17337         }
17338     }
17339
17340     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17341         synchronized(this) {
17342             if (!(token instanceof ServiceRecord)) {
17343                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17344                 throw new IllegalArgumentException("Invalid service token");
17345             }
17346             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17347         }
17348     }
17349
17350     // =========================================================
17351     // BACKUP AND RESTORE
17352     // =========================================================
17353
17354     // Cause the target app to be launched if necessary and its backup agent
17355     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17356     // activity manager to announce its creation.
17357     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17358         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17359         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17360
17361         IPackageManager pm = AppGlobals.getPackageManager();
17362         ApplicationInfo app = null;
17363         try {
17364             app = pm.getApplicationInfo(packageName, 0, userId);
17365         } catch (RemoteException e) {
17366             // can't happen; package manager is process-local
17367         }
17368         if (app == null) {
17369             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17370             return false;
17371         }
17372
17373         synchronized(this) {
17374             // !!! TODO: currently no check here that we're already bound
17375             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17376             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17377             synchronized (stats) {
17378                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17379             }
17380
17381             // Backup agent is now in use, its package can't be stopped.
17382             try {
17383                 AppGlobals.getPackageManager().setPackageStoppedState(
17384                         app.packageName, false, UserHandle.getUserId(app.uid));
17385             } catch (RemoteException e) {
17386             } catch (IllegalArgumentException e) {
17387                 Slog.w(TAG, "Failed trying to unstop package "
17388                         + app.packageName + ": " + e);
17389             }
17390
17391             BackupRecord r = new BackupRecord(ss, app, backupMode);
17392             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17393                     ? new ComponentName(app.packageName, app.backupAgentName)
17394                     : new ComponentName("android", "FullBackupAgent");
17395             // startProcessLocked() returns existing proc's record if it's already running
17396             ProcessRecord proc = startProcessLocked(app.processName, app,
17397                     false, 0, "backup", hostingName, false, false, false);
17398             if (proc == null) {
17399                 Slog.e(TAG, "Unable to start backup agent process " + r);
17400                 return false;
17401             }
17402
17403             // If the app is a regular app (uid >= 10000) and not the system server or phone
17404             // process, etc, then mark it as being in full backup so that certain calls to the
17405             // process can be blocked. This is not reset to false anywhere because we kill the
17406             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17407             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17408                 proc.inFullBackup = true;
17409             }
17410             r.app = proc;
17411             mBackupTarget = r;
17412             mBackupAppName = app.packageName;
17413
17414             // Try not to kill the process during backup
17415             updateOomAdjLocked(proc);
17416
17417             // If the process is already attached, schedule the creation of the backup agent now.
17418             // If it is not yet live, this will be done when it attaches to the framework.
17419             if (proc.thread != null) {
17420                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17421                 try {
17422                     proc.thread.scheduleCreateBackupAgent(app,
17423                             compatibilityInfoForPackageLocked(app), backupMode);
17424                 } catch (RemoteException e) {
17425                     // Will time out on the backup manager side
17426                 }
17427             } else {
17428                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17429             }
17430             // Invariants: at this point, the target app process exists and the application
17431             // is either already running or in the process of coming up.  mBackupTarget and
17432             // mBackupAppName describe the app, so that when it binds back to the AM we
17433             // know that it's scheduled for a backup-agent operation.
17434         }
17435
17436         return true;
17437     }
17438
17439     @Override
17440     public void clearPendingBackup() {
17441         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17442         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17443
17444         synchronized (this) {
17445             mBackupTarget = null;
17446             mBackupAppName = null;
17447         }
17448     }
17449
17450     // A backup agent has just come up
17451     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17452         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17453                 + " = " + agent);
17454
17455         synchronized(this) {
17456             if (!agentPackageName.equals(mBackupAppName)) {
17457                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17458                 return;
17459             }
17460         }
17461
17462         long oldIdent = Binder.clearCallingIdentity();
17463         try {
17464             IBackupManager bm = IBackupManager.Stub.asInterface(
17465                     ServiceManager.getService(Context.BACKUP_SERVICE));
17466             bm.agentConnected(agentPackageName, agent);
17467         } catch (RemoteException e) {
17468             // can't happen; the backup manager service is local
17469         } catch (Exception e) {
17470             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17471             e.printStackTrace();
17472         } finally {
17473             Binder.restoreCallingIdentity(oldIdent);
17474         }
17475     }
17476
17477     // done with this agent
17478     public void unbindBackupAgent(ApplicationInfo appInfo) {
17479         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17480         if (appInfo == null) {
17481             Slog.w(TAG, "unbind backup agent for null app");
17482             return;
17483         }
17484
17485         synchronized(this) {
17486             try {
17487                 if (mBackupAppName == null) {
17488                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17489                     return;
17490                 }
17491
17492                 if (!mBackupAppName.equals(appInfo.packageName)) {
17493                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17494                     return;
17495                 }
17496
17497                 // Not backing this app up any more; reset its OOM adjustment
17498                 final ProcessRecord proc = mBackupTarget.app;
17499                 updateOomAdjLocked(proc);
17500
17501                 // If the app crashed during backup, 'thread' will be null here
17502                 if (proc.thread != null) {
17503                     try {
17504                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17505                                 compatibilityInfoForPackageLocked(appInfo));
17506                     } catch (Exception e) {
17507                         Slog.e(TAG, "Exception when unbinding backup agent:");
17508                         e.printStackTrace();
17509                     }
17510                 }
17511             } finally {
17512                 mBackupTarget = null;
17513                 mBackupAppName = null;
17514             }
17515         }
17516     }
17517     // =========================================================
17518     // BROADCASTS
17519     // =========================================================
17520
17521     boolean isPendingBroadcastProcessLocked(int pid) {
17522         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17523                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17524     }
17525
17526     void skipPendingBroadcastLocked(int pid) {
17527             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17528             for (BroadcastQueue queue : mBroadcastQueues) {
17529                 queue.skipPendingBroadcastLocked(pid);
17530             }
17531     }
17532
17533     // The app just attached; send any pending broadcasts that it should receive
17534     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17535         boolean didSomething = false;
17536         for (BroadcastQueue queue : mBroadcastQueues) {
17537             didSomething |= queue.sendPendingBroadcastsLocked(app);
17538         }
17539         return didSomething;
17540     }
17541
17542     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17543             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17544         enforceNotIsolatedCaller("registerReceiver");
17545         ArrayList<Intent> stickyIntents = null;
17546         ProcessRecord callerApp = null;
17547         int callingUid;
17548         int callingPid;
17549         synchronized(this) {
17550             if (caller != null) {
17551                 callerApp = getRecordForAppLocked(caller);
17552                 if (callerApp == null) {
17553                     throw new SecurityException(
17554                             "Unable to find app for caller " + caller
17555                             + " (pid=" + Binder.getCallingPid()
17556                             + ") when registering receiver " + receiver);
17557                 }
17558                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17559                         !callerApp.pkgList.containsKey(callerPackage) &&
17560                         !"android".equals(callerPackage)) {
17561                     throw new SecurityException("Given caller package " + callerPackage
17562                             + " is not running in process " + callerApp);
17563                 }
17564                 callingUid = callerApp.info.uid;
17565                 callingPid = callerApp.pid;
17566             } else {
17567                 callerPackage = null;
17568                 callingUid = Binder.getCallingUid();
17569                 callingPid = Binder.getCallingPid();
17570             }
17571
17572             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17573                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17574
17575             Iterator<String> actions = filter.actionsIterator();
17576             if (actions == null) {
17577                 ArrayList<String> noAction = new ArrayList<String>(1);
17578                 noAction.add(null);
17579                 actions = noAction.iterator();
17580             }
17581
17582             // Collect stickies of users
17583             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17584             while (actions.hasNext()) {
17585                 String action = actions.next();
17586                 for (int id : userIds) {
17587                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17588                     if (stickies != null) {
17589                         ArrayList<Intent> intents = stickies.get(action);
17590                         if (intents != null) {
17591                             if (stickyIntents == null) {
17592                                 stickyIntents = new ArrayList<Intent>();
17593                             }
17594                             stickyIntents.addAll(intents);
17595                         }
17596                     }
17597                 }
17598             }
17599         }
17600
17601         ArrayList<Intent> allSticky = null;
17602         if (stickyIntents != null) {
17603             final ContentResolver resolver = mContext.getContentResolver();
17604             // Look for any matching sticky broadcasts...
17605             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17606                 Intent intent = stickyIntents.get(i);
17607                 // If intent has scheme "content", it will need to acccess
17608                 // provider that needs to lock mProviderMap in ActivityThread
17609                 // and also it may need to wait application response, so we
17610                 // cannot lock ActivityManagerService here.
17611                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17612                     if (allSticky == null) {
17613                         allSticky = new ArrayList<Intent>();
17614                     }
17615                     allSticky.add(intent);
17616                 }
17617             }
17618         }
17619
17620         // The first sticky in the list is returned directly back to the client.
17621         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17622         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17623         if (receiver == null) {
17624             return sticky;
17625         }
17626
17627         synchronized (this) {
17628             if (callerApp != null && (callerApp.thread == null
17629                     || callerApp.thread.asBinder() != caller.asBinder())) {
17630                 // Original caller already died
17631                 return null;
17632             }
17633             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17634             if (rl == null) {
17635                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17636                         userId, receiver);
17637                 if (rl.app != null) {
17638                     rl.app.receivers.add(rl);
17639                 } else {
17640                     try {
17641                         receiver.asBinder().linkToDeath(rl, 0);
17642                     } catch (RemoteException e) {
17643                         return sticky;
17644                     }
17645                     rl.linkedToDeath = true;
17646                 }
17647                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17648             } else if (rl.uid != callingUid) {
17649                 throw new IllegalArgumentException(
17650                         "Receiver requested to register for uid " + callingUid
17651                         + " was previously registered for uid " + rl.uid);
17652             } else if (rl.pid != callingPid) {
17653                 throw new IllegalArgumentException(
17654                         "Receiver requested to register for pid " + callingPid
17655                         + " was previously registered for pid " + rl.pid);
17656             } else if (rl.userId != userId) {
17657                 throw new IllegalArgumentException(
17658                         "Receiver requested to register for user " + userId
17659                         + " was previously registered for user " + rl.userId);
17660             }
17661             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17662                     permission, callingUid, userId);
17663             rl.add(bf);
17664             if (!bf.debugCheck()) {
17665                 Slog.w(TAG, "==> For Dynamic broadcast");
17666             }
17667             mReceiverResolver.addFilter(bf);
17668
17669             // Enqueue broadcasts for all existing stickies that match
17670             // this filter.
17671             if (allSticky != null) {
17672                 ArrayList receivers = new ArrayList();
17673                 receivers.add(bf);
17674
17675                 final int stickyCount = allSticky.size();
17676                 for (int i = 0; i < stickyCount; i++) {
17677                     Intent intent = allSticky.get(i);
17678                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17679                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17680                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17681                             null, 0, null, null, false, true, true, -1);
17682                     queue.enqueueParallelBroadcastLocked(r);
17683                     queue.scheduleBroadcastsLocked();
17684                 }
17685             }
17686
17687             return sticky;
17688         }
17689     }
17690
17691     public void unregisterReceiver(IIntentReceiver receiver) {
17692         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17693
17694         final long origId = Binder.clearCallingIdentity();
17695         try {
17696             boolean doTrim = false;
17697
17698             synchronized(this) {
17699                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17700                 if (rl != null) {
17701                     final BroadcastRecord r = rl.curBroadcast;
17702                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17703                         final boolean doNext = r.queue.finishReceiverLocked(
17704                                 r, r.resultCode, r.resultData, r.resultExtras,
17705                                 r.resultAbort, false);
17706                         if (doNext) {
17707                             doTrim = true;
17708                             r.queue.processNextBroadcast(false);
17709                         }
17710                     }
17711
17712                     if (rl.app != null) {
17713                         rl.app.receivers.remove(rl);
17714                     }
17715                     removeReceiverLocked(rl);
17716                     if (rl.linkedToDeath) {
17717                         rl.linkedToDeath = false;
17718                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17719                     }
17720                 }
17721             }
17722
17723             // If we actually concluded any broadcasts, we might now be able
17724             // to trim the recipients' apps from our working set
17725             if (doTrim) {
17726                 trimApplications();
17727                 return;
17728             }
17729
17730         } finally {
17731             Binder.restoreCallingIdentity(origId);
17732         }
17733     }
17734
17735     void removeReceiverLocked(ReceiverList rl) {
17736         mRegisteredReceivers.remove(rl.receiver.asBinder());
17737         for (int i = rl.size() - 1; i >= 0; i--) {
17738             mReceiverResolver.removeFilter(rl.get(i));
17739         }
17740     }
17741
17742     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17743         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17744             ProcessRecord r = mLruProcesses.get(i);
17745             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17746                 try {
17747                     r.thread.dispatchPackageBroadcast(cmd, packages);
17748                 } catch (RemoteException ex) {
17749                 }
17750             }
17751         }
17752     }
17753
17754     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17755             int callingUid, int[] users) {
17756         // TODO: come back and remove this assumption to triage all broadcasts
17757         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17758
17759         List<ResolveInfo> receivers = null;
17760         try {
17761             HashSet<ComponentName> singleUserReceivers = null;
17762             boolean scannedFirstReceivers = false;
17763             for (int user : users) {
17764                 // Skip users that have Shell restrictions, with exception of always permitted
17765                 // Shell broadcasts
17766                 if (callingUid == Process.SHELL_UID
17767                         && mUserController.hasUserRestriction(
17768                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17769                         && !isPermittedShellBroadcast(intent)) {
17770                     continue;
17771                 }
17772                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17773                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17774                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17775                     // If this is not the system user, we need to check for
17776                     // any receivers that should be filtered out.
17777                     for (int i=0; i<newReceivers.size(); i++) {
17778                         ResolveInfo ri = newReceivers.get(i);
17779                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17780                             newReceivers.remove(i);
17781                             i--;
17782                         }
17783                     }
17784                 }
17785                 if (newReceivers != null && newReceivers.size() == 0) {
17786                     newReceivers = null;
17787                 }
17788                 if (receivers == null) {
17789                     receivers = newReceivers;
17790                 } else if (newReceivers != null) {
17791                     // We need to concatenate the additional receivers
17792                     // found with what we have do far.  This would be easy,
17793                     // but we also need to de-dup any receivers that are
17794                     // singleUser.
17795                     if (!scannedFirstReceivers) {
17796                         // Collect any single user receivers we had already retrieved.
17797                         scannedFirstReceivers = true;
17798                         for (int i=0; i<receivers.size(); i++) {
17799                             ResolveInfo ri = receivers.get(i);
17800                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17801                                 ComponentName cn = new ComponentName(
17802                                         ri.activityInfo.packageName, ri.activityInfo.name);
17803                                 if (singleUserReceivers == null) {
17804                                     singleUserReceivers = new HashSet<ComponentName>();
17805                                 }
17806                                 singleUserReceivers.add(cn);
17807                             }
17808                         }
17809                     }
17810                     // Add the new results to the existing results, tracking
17811                     // and de-dupping single user receivers.
17812                     for (int i=0; i<newReceivers.size(); i++) {
17813                         ResolveInfo ri = newReceivers.get(i);
17814                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17815                             ComponentName cn = new ComponentName(
17816                                     ri.activityInfo.packageName, ri.activityInfo.name);
17817                             if (singleUserReceivers == null) {
17818                                 singleUserReceivers = new HashSet<ComponentName>();
17819                             }
17820                             if (!singleUserReceivers.contains(cn)) {
17821                                 singleUserReceivers.add(cn);
17822                                 receivers.add(ri);
17823                             }
17824                         } else {
17825                             receivers.add(ri);
17826                         }
17827                     }
17828                 }
17829             }
17830         } catch (RemoteException ex) {
17831             // pm is in same process, this will never happen.
17832         }
17833         return receivers;
17834     }
17835
17836     private boolean isPermittedShellBroadcast(Intent intent) {
17837         // remote bugreport should always be allowed to be taken
17838         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17839     }
17840
17841     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17842             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17843         final String action = intent.getAction();
17844         if (isProtectedBroadcast
17845                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17846                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17847                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17848                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17849                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17850                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17851                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17852                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17853                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17854                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17855             // Broadcast is either protected, or it's a public action that
17856             // we've relaxed, so it's fine for system internals to send.
17857             return;
17858         }
17859
17860         // This broadcast may be a problem...  but there are often system components that
17861         // want to send an internal broadcast to themselves, which is annoying to have to
17862         // explicitly list each action as a protected broadcast, so we will check for that
17863         // one safe case and allow it: an explicit broadcast, only being received by something
17864         // that has protected itself.
17865         if (receivers != null && receivers.size() > 0
17866                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17867             boolean allProtected = true;
17868             for (int i = receivers.size()-1; i >= 0; i--) {
17869                 Object target = receivers.get(i);
17870                 if (target instanceof ResolveInfo) {
17871                     ResolveInfo ri = (ResolveInfo)target;
17872                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17873                         allProtected = false;
17874                         break;
17875                     }
17876                 } else {
17877                     BroadcastFilter bf = (BroadcastFilter)target;
17878                     if (bf.requiredPermission == null) {
17879                         allProtected = false;
17880                         break;
17881                     }
17882                 }
17883             }
17884             if (allProtected) {
17885                 // All safe!
17886                 return;
17887             }
17888         }
17889
17890         // The vast majority of broadcasts sent from system internals
17891         // should be protected to avoid security holes, so yell loudly
17892         // to ensure we examine these cases.
17893         if (callerApp != null) {
17894             Log.wtf(TAG, "Sending non-protected broadcast " + action
17895                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17896                     new Throwable());
17897         } else {
17898             Log.wtf(TAG, "Sending non-protected broadcast " + action
17899                             + " from system uid " + UserHandle.formatUid(callingUid)
17900                             + " pkg " + callerPackage,
17901                     new Throwable());
17902         }
17903     }
17904
17905     final int broadcastIntentLocked(ProcessRecord callerApp,
17906             String callerPackage, Intent intent, String resolvedType,
17907             IIntentReceiver resultTo, int resultCode, String resultData,
17908             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17909             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17910         intent = new Intent(intent);
17911
17912         // By default broadcasts do not go to stopped apps.
17913         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17914
17915         // If we have not finished booting, don't allow this to launch new processes.
17916         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17917             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17918         }
17919
17920         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17921                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17922                 + " ordered=" + ordered + " userid=" + userId);
17923         if ((resultTo != null) && !ordered) {
17924             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17925         }
17926
17927         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17928                 ALLOW_NON_FULL, "broadcast", callerPackage);
17929
17930         // Make sure that the user who is receiving this broadcast is running.
17931         // If not, we will just skip it. Make an exception for shutdown broadcasts
17932         // and upgrade steps.
17933
17934         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17935             if ((callingUid != Process.SYSTEM_UID
17936                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17937                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17938                 Slog.w(TAG, "Skipping broadcast of " + intent
17939                         + ": user " + userId + " is stopped");
17940                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17941             }
17942         }
17943
17944         BroadcastOptions brOptions = null;
17945         if (bOptions != null) {
17946             brOptions = new BroadcastOptions(bOptions);
17947             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17948                 // See if the caller is allowed to do this.  Note we are checking against
17949                 // the actual real caller (not whoever provided the operation as say a
17950                 // PendingIntent), because that who is actually supplied the arguments.
17951                 if (checkComponentPermission(
17952                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17953                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17954                         != PackageManager.PERMISSION_GRANTED) {
17955                     String msg = "Permission Denial: " + intent.getAction()
17956                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17957                             + ", uid=" + callingUid + ")"
17958                             + " requires "
17959                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17960                     Slog.w(TAG, msg);
17961                     throw new SecurityException(msg);
17962                 }
17963             }
17964         }
17965
17966         // Verify that protected broadcasts are only being sent by system code,
17967         // and that system code is only sending protected broadcasts.
17968         final String action = intent.getAction();
17969         final boolean isProtectedBroadcast;
17970         try {
17971             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17972         } catch (RemoteException e) {
17973             Slog.w(TAG, "Remote exception", e);
17974             return ActivityManager.BROADCAST_SUCCESS;
17975         }
17976
17977         final boolean isCallerSystem;
17978         switch (UserHandle.getAppId(callingUid)) {
17979             case Process.ROOT_UID:
17980             case Process.SYSTEM_UID:
17981             case Process.PHONE_UID:
17982             case Process.BLUETOOTH_UID:
17983             case Process.NFC_UID:
17984                 isCallerSystem = true;
17985                 break;
17986             default:
17987                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17988                 break;
17989         }
17990
17991         // First line security check before anything else: stop non-system apps from
17992         // sending protected broadcasts.
17993         if (!isCallerSystem) {
17994             if (isProtectedBroadcast) {
17995                 String msg = "Permission Denial: not allowed to send broadcast "
17996                         + action + " from pid="
17997                         + callingPid + ", uid=" + callingUid;
17998                 Slog.w(TAG, msg);
17999                 throw new SecurityException(msg);
18000
18001             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18002                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18003                 // Special case for compatibility: we don't want apps to send this,
18004                 // but historically it has not been protected and apps may be using it
18005                 // to poke their own app widget.  So, instead of making it protected,
18006                 // just limit it to the caller.
18007                 if (callerPackage == null) {
18008                     String msg = "Permission Denial: not allowed to send broadcast "
18009                             + action + " from unknown caller.";
18010                     Slog.w(TAG, msg);
18011                     throw new SecurityException(msg);
18012                 } else if (intent.getComponent() != null) {
18013                     // They are good enough to send to an explicit component...  verify
18014                     // it is being sent to the calling app.
18015                     if (!intent.getComponent().getPackageName().equals(
18016                             callerPackage)) {
18017                         String msg = "Permission Denial: not allowed to send broadcast "
18018                                 + action + " to "
18019                                 + intent.getComponent().getPackageName() + " from "
18020                                 + callerPackage;
18021                         Slog.w(TAG, msg);
18022                         throw new SecurityException(msg);
18023                     }
18024                 } else {
18025                     // Limit broadcast to their own package.
18026                     intent.setPackage(callerPackage);
18027                 }
18028             }
18029         }
18030
18031         if (action != null) {
18032             switch (action) {
18033                 case Intent.ACTION_UID_REMOVED:
18034                 case Intent.ACTION_PACKAGE_REMOVED:
18035                 case Intent.ACTION_PACKAGE_CHANGED:
18036                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18037                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18038                 case Intent.ACTION_PACKAGES_SUSPENDED:
18039                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18040                     // Handle special intents: if this broadcast is from the package
18041                     // manager about a package being removed, we need to remove all of
18042                     // its activities from the history stack.
18043                     if (checkComponentPermission(
18044                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18045                             callingPid, callingUid, -1, true)
18046                             != PackageManager.PERMISSION_GRANTED) {
18047                         String msg = "Permission Denial: " + intent.getAction()
18048                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
18049                                 + ", uid=" + callingUid + ")"
18050                                 + " requires "
18051                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18052                         Slog.w(TAG, msg);
18053                         throw new SecurityException(msg);
18054                     }
18055                     switch (action) {
18056                         case Intent.ACTION_UID_REMOVED:
18057                             final Bundle intentExtras = intent.getExtras();
18058                             final int uid = intentExtras != null
18059                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18060                             if (uid >= 0) {
18061                                 mBatteryStatsService.removeUid(uid);
18062                                 mAppOpsService.uidRemoved(uid);
18063                             }
18064                             break;
18065                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18066                             // If resources are unavailable just force stop all those packages
18067                             // and flush the attribute cache as well.
18068                             String list[] =
18069                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18070                             if (list != null && list.length > 0) {
18071                                 for (int i = 0; i < list.length; i++) {
18072                                     forceStopPackageLocked(list[i], -1, false, true, true,
18073                                             false, false, userId, "storage unmount");
18074                                 }
18075                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18076                                 sendPackageBroadcastLocked(
18077                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18078                                         userId);
18079                             }
18080                             break;
18081                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18082                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18083                             break;
18084                         case Intent.ACTION_PACKAGE_REMOVED:
18085                         case Intent.ACTION_PACKAGE_CHANGED:
18086                             Uri data = intent.getData();
18087                             String ssp;
18088                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18089                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18090                                 final boolean replacing =
18091                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18092                                 final boolean killProcess =
18093                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18094                                 final boolean fullUninstall = removed && !replacing;
18095                                 if (removed) {
18096                                     if (killProcess) {
18097                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18098                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18099                                                 false, true, true, false, fullUninstall, userId,
18100                                                 removed ? "pkg removed" : "pkg changed");
18101                                     }
18102                                     final int cmd = killProcess
18103                                             ? IApplicationThread.PACKAGE_REMOVED
18104                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18105                                     sendPackageBroadcastLocked(cmd,
18106                                             new String[] {ssp}, userId);
18107                                     if (fullUninstall) {
18108                                         mAppOpsService.packageRemoved(
18109                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18110
18111                                         // Remove all permissions granted from/to this package
18112                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18113
18114                                         removeTasksByPackageNameLocked(ssp, userId);
18115
18116                                         // Hide the "unsupported display" dialog if necessary.
18117                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18118                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18119                                             mUnsupportedDisplaySizeDialog.dismiss();
18120                                             mUnsupportedDisplaySizeDialog = null;
18121                                         }
18122                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18123                                         mBatteryStatsService.notePackageUninstalled(ssp);
18124                                     }
18125                                 } else {
18126                                     if (killProcess) {
18127                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18128                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18129                                                 userId, ProcessList.INVALID_ADJ,
18130                                                 false, true, true, false, "change " + ssp);
18131                                     }
18132                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18133                                             intent.getStringArrayExtra(
18134                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18135                                 }
18136                             }
18137                             break;
18138                         case Intent.ACTION_PACKAGES_SUSPENDED:
18139                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18140                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18141                                     intent.getAction());
18142                             final String[] packageNames = intent.getStringArrayExtra(
18143                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18144                             final int userHandle = intent.getIntExtra(
18145                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18146
18147                             synchronized(ActivityManagerService.this) {
18148                                 mRecentTasks.onPackagesSuspendedChanged(
18149                                         packageNames, suspended, userHandle);
18150                             }
18151                             break;
18152                     }
18153                     break;
18154                 case Intent.ACTION_PACKAGE_REPLACED:
18155                 {
18156                     final Uri data = intent.getData();
18157                     final String ssp;
18158                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18159                         final ApplicationInfo aInfo =
18160                                 getPackageManagerInternalLocked().getApplicationInfo(
18161                                         ssp,
18162                                         userId);
18163                         if (aInfo == null) {
18164                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18165                                     + " ssp=" + ssp + " data=" + data);
18166                             return ActivityManager.BROADCAST_SUCCESS;
18167                         }
18168                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18169                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18170                                 new String[] {ssp}, userId);
18171                     }
18172                     break;
18173                 }
18174                 case Intent.ACTION_PACKAGE_ADDED:
18175                 {
18176                     // Special case for adding a package: by default turn on compatibility mode.
18177                     Uri data = intent.getData();
18178                     String ssp;
18179                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18180                         final boolean replacing =
18181                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18182                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18183
18184                         try {
18185                             ApplicationInfo ai = AppGlobals.getPackageManager().
18186                                     getApplicationInfo(ssp, 0, 0);
18187                             mBatteryStatsService.notePackageInstalled(ssp,
18188                                     ai != null ? ai.versionCode : 0);
18189                         } catch (RemoteException e) {
18190                         }
18191                     }
18192                     break;
18193                 }
18194                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18195                 {
18196                     Uri data = intent.getData();
18197                     String ssp;
18198                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18199                         // Hide the "unsupported display" dialog if necessary.
18200                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18201                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18202                             mUnsupportedDisplaySizeDialog.dismiss();
18203                             mUnsupportedDisplaySizeDialog = null;
18204                         }
18205                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18206                     }
18207                     break;
18208                 }
18209                 case Intent.ACTION_TIMEZONE_CHANGED:
18210                     // If this is the time zone changed action, queue up a message that will reset
18211                     // the timezone of all currently running processes. This message will get
18212                     // queued up before the broadcast happens.
18213                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18214                     break;
18215                 case Intent.ACTION_TIME_CHANGED:
18216                     // If the user set the time, let all running processes know.
18217                     final int is24Hour =
18218                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18219                                     : 0;
18220                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18221                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18222                     synchronized (stats) {
18223                         stats.noteCurrentTimeChangedLocked();
18224                     }
18225                     break;
18226                 case Intent.ACTION_CLEAR_DNS_CACHE:
18227                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18228                     break;
18229                 case Proxy.PROXY_CHANGE_ACTION:
18230                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18231                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18232                     break;
18233                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18234                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18235                     // These broadcasts are no longer allowed by the system, since they can
18236                     // cause significant thrashing at a crictical point (using the camera).
18237                     // Apps should use JobScehduler to monitor for media provider changes.
18238                     Slog.w(TAG, action + " no longer allowed; dropping from "
18239                             + UserHandle.formatUid(callingUid));
18240                     if (resultTo != null) {
18241                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18242                         try {
18243                             queue.performReceiveLocked(callerApp, resultTo, intent,
18244                                     Activity.RESULT_CANCELED, null, null,
18245                                     false, false, userId);
18246                         } catch (RemoteException e) {
18247                             Slog.w(TAG, "Failure ["
18248                                     + queue.mQueueName + "] sending broadcast result of "
18249                                     + intent, e);
18250
18251                         }
18252                     }
18253                     // Lie; we don't want to crash the app.
18254                     return ActivityManager.BROADCAST_SUCCESS;
18255             }
18256         }
18257
18258         // Add to the sticky list if requested.
18259         if (sticky) {
18260             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18261                     callingPid, callingUid)
18262                     != PackageManager.PERMISSION_GRANTED) {
18263                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18264                         + callingPid + ", uid=" + callingUid
18265                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18266                 Slog.w(TAG, msg);
18267                 throw new SecurityException(msg);
18268             }
18269             if (requiredPermissions != null && requiredPermissions.length > 0) {
18270                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18271                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18272                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18273             }
18274             if (intent.getComponent() != null) {
18275                 throw new SecurityException(
18276                         "Sticky broadcasts can't target a specific component");
18277             }
18278             // We use userId directly here, since the "all" target is maintained
18279             // as a separate set of sticky broadcasts.
18280             if (userId != UserHandle.USER_ALL) {
18281                 // But first, if this is not a broadcast to all users, then
18282                 // make sure it doesn't conflict with an existing broadcast to
18283                 // all users.
18284                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18285                         UserHandle.USER_ALL);
18286                 if (stickies != null) {
18287                     ArrayList<Intent> list = stickies.get(intent.getAction());
18288                     if (list != null) {
18289                         int N = list.size();
18290                         int i;
18291                         for (i=0; i<N; i++) {
18292                             if (intent.filterEquals(list.get(i))) {
18293                                 throw new IllegalArgumentException(
18294                                         "Sticky broadcast " + intent + " for user "
18295                                         + userId + " conflicts with existing global broadcast");
18296                             }
18297                         }
18298                     }
18299                 }
18300             }
18301             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18302             if (stickies == null) {
18303                 stickies = new ArrayMap<>();
18304                 mStickyBroadcasts.put(userId, stickies);
18305             }
18306             ArrayList<Intent> list = stickies.get(intent.getAction());
18307             if (list == null) {
18308                 list = new ArrayList<>();
18309                 stickies.put(intent.getAction(), list);
18310             }
18311             final int stickiesCount = list.size();
18312             int i;
18313             for (i = 0; i < stickiesCount; i++) {
18314                 if (intent.filterEquals(list.get(i))) {
18315                     // This sticky already exists, replace it.
18316                     list.set(i, new Intent(intent));
18317                     break;
18318                 }
18319             }
18320             if (i >= stickiesCount) {
18321                 list.add(new Intent(intent));
18322             }
18323         }
18324
18325         int[] users;
18326         if (userId == UserHandle.USER_ALL) {
18327             // Caller wants broadcast to go to all started users.
18328             users = mUserController.getStartedUserArrayLocked();
18329         } else {
18330             // Caller wants broadcast to go to one specific user.
18331             users = new int[] {userId};
18332         }
18333
18334         // Figure out who all will receive this broadcast.
18335         List receivers = null;
18336         List<BroadcastFilter> registeredReceivers = null;
18337         // Need to resolve the intent to interested receivers...
18338         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18339                  == 0) {
18340             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18341         }
18342         if (intent.getComponent() == null) {
18343             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18344                 // Query one target user at a time, excluding shell-restricted users
18345                 for (int i = 0; i < users.length; i++) {
18346                     if (mUserController.hasUserRestriction(
18347                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18348                         continue;
18349                     }
18350                     List<BroadcastFilter> registeredReceiversForUser =
18351                             mReceiverResolver.queryIntent(intent,
18352                                     resolvedType, false, users[i]);
18353                     if (registeredReceivers == null) {
18354                         registeredReceivers = registeredReceiversForUser;
18355                     } else if (registeredReceiversForUser != null) {
18356                         registeredReceivers.addAll(registeredReceiversForUser);
18357                     }
18358                 }
18359             } else {
18360                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18361                         resolvedType, false, userId);
18362             }
18363         }
18364
18365         final boolean replacePending =
18366                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18367
18368         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18369                 + " replacePending=" + replacePending);
18370
18371         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18372         if (!ordered && NR > 0) {
18373             // If we are not serializing this broadcast, then send the
18374             // registered receivers separately so they don't wait for the
18375             // components to be launched.
18376             if (isCallerSystem) {
18377                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18378                         isProtectedBroadcast, registeredReceivers);
18379             }
18380             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18381             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18382                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18383                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18384                     resultExtras, ordered, sticky, false, userId);
18385             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18386             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18387             if (!replaced) {
18388                 queue.enqueueParallelBroadcastLocked(r);
18389                 queue.scheduleBroadcastsLocked();
18390             }
18391             registeredReceivers = null;
18392             NR = 0;
18393         }
18394
18395         // Merge into one list.
18396         int ir = 0;
18397         if (receivers != null) {
18398             // A special case for PACKAGE_ADDED: do not allow the package
18399             // being added to see this broadcast.  This prevents them from
18400             // using this as a back door to get run as soon as they are
18401             // installed.  Maybe in the future we want to have a special install
18402             // broadcast or such for apps, but we'd like to deliberately make
18403             // this decision.
18404             String skipPackages[] = null;
18405             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18406                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18407                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18408                 Uri data = intent.getData();
18409                 if (data != null) {
18410                     String pkgName = data.getSchemeSpecificPart();
18411                     if (pkgName != null) {
18412                         skipPackages = new String[] { pkgName };
18413                     }
18414                 }
18415             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18416                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18417             }
18418             if (skipPackages != null && (skipPackages.length > 0)) {
18419                 for (String skipPackage : skipPackages) {
18420                     if (skipPackage != null) {
18421                         int NT = receivers.size();
18422                         for (int it=0; it<NT; it++) {
18423                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18424                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18425                                 receivers.remove(it);
18426                                 it--;
18427                                 NT--;
18428                             }
18429                         }
18430                     }
18431                 }
18432             }
18433
18434             int NT = receivers != null ? receivers.size() : 0;
18435             int it = 0;
18436             ResolveInfo curt = null;
18437             BroadcastFilter curr = null;
18438             while (it < NT && ir < NR) {
18439                 if (curt == null) {
18440                     curt = (ResolveInfo)receivers.get(it);
18441                 }
18442                 if (curr == null) {
18443                     curr = registeredReceivers.get(ir);
18444                 }
18445                 if (curr.getPriority() >= curt.priority) {
18446                     // Insert this broadcast record into the final list.
18447                     receivers.add(it, curr);
18448                     ir++;
18449                     curr = null;
18450                     it++;
18451                     NT++;
18452                 } else {
18453                     // Skip to the next ResolveInfo in the final list.
18454                     it++;
18455                     curt = null;
18456                 }
18457             }
18458         }
18459         while (ir < NR) {
18460             if (receivers == null) {
18461                 receivers = new ArrayList();
18462             }
18463             receivers.add(registeredReceivers.get(ir));
18464             ir++;
18465         }
18466
18467         if (isCallerSystem) {
18468             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18469                     isProtectedBroadcast, receivers);
18470         }
18471
18472         if ((receivers != null && receivers.size() > 0)
18473                 || resultTo != null) {
18474             BroadcastQueue queue = broadcastQueueForIntent(intent);
18475             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18476                     callerPackage, callingPid, callingUid, resolvedType,
18477                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18478                     resultData, resultExtras, ordered, sticky, false, userId);
18479
18480             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18481                     + ": prev had " + queue.mOrderedBroadcasts.size());
18482             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18483                     "Enqueueing broadcast " + r.intent.getAction());
18484
18485             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18486             if (!replaced) {
18487                 queue.enqueueOrderedBroadcastLocked(r);
18488                 queue.scheduleBroadcastsLocked();
18489             }
18490         } else {
18491             // There was nobody interested in the broadcast, but we still want to record
18492             // that it happened.
18493             if (intent.getComponent() == null && intent.getPackage() == null
18494                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18495                 // This was an implicit broadcast... let's record it for posterity.
18496                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18497             }
18498         }
18499
18500         return ActivityManager.BROADCAST_SUCCESS;
18501     }
18502
18503     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18504             int skipCount, long dispatchTime) {
18505         final long now = SystemClock.elapsedRealtime();
18506         if (mCurBroadcastStats == null ||
18507                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18508             mLastBroadcastStats = mCurBroadcastStats;
18509             if (mLastBroadcastStats != null) {
18510                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18511                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18512             }
18513             mCurBroadcastStats = new BroadcastStats();
18514         }
18515         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18516     }
18517
18518     final Intent verifyBroadcastLocked(Intent intent) {
18519         // Refuse possible leaked file descriptors
18520         if (intent != null && intent.hasFileDescriptors() == true) {
18521             throw new IllegalArgumentException("File descriptors passed in Intent");
18522         }
18523
18524         int flags = intent.getFlags();
18525
18526         if (!mProcessesReady) {
18527             // if the caller really truly claims to know what they're doing, go
18528             // ahead and allow the broadcast without launching any receivers
18529             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18530                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18531             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18532                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18533                         + " before boot completion");
18534                 throw new IllegalStateException("Cannot broadcast before boot completed");
18535             }
18536         }
18537
18538         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18539             throw new IllegalArgumentException(
18540                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18541         }
18542
18543         return intent;
18544     }
18545
18546     public final int broadcastIntent(IApplicationThread caller,
18547             Intent intent, String resolvedType, IIntentReceiver resultTo,
18548             int resultCode, String resultData, Bundle resultExtras,
18549             String[] requiredPermissions, int appOp, Bundle bOptions,
18550             boolean serialized, boolean sticky, int userId) {
18551         enforceNotIsolatedCaller("broadcastIntent");
18552         synchronized(this) {
18553             intent = verifyBroadcastLocked(intent);
18554
18555             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18556             final int callingPid = Binder.getCallingPid();
18557             final int callingUid = Binder.getCallingUid();
18558             final long origId = Binder.clearCallingIdentity();
18559             int res = broadcastIntentLocked(callerApp,
18560                     callerApp != null ? callerApp.info.packageName : null,
18561                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18562                     requiredPermissions, appOp, bOptions, serialized, sticky,
18563                     callingPid, callingUid, userId);
18564             Binder.restoreCallingIdentity(origId);
18565             return res;
18566         }
18567     }
18568
18569
18570     int broadcastIntentInPackage(String packageName, int uid,
18571             Intent intent, String resolvedType, IIntentReceiver resultTo,
18572             int resultCode, String resultData, Bundle resultExtras,
18573             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18574             int userId) {
18575         synchronized(this) {
18576             intent = verifyBroadcastLocked(intent);
18577
18578             final long origId = Binder.clearCallingIdentity();
18579             String[] requiredPermissions = requiredPermission == null ? null
18580                     : new String[] {requiredPermission};
18581             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18582                     resultTo, resultCode, resultData, resultExtras,
18583                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18584                     sticky, -1, uid, userId);
18585             Binder.restoreCallingIdentity(origId);
18586             return res;
18587         }
18588     }
18589
18590     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18591         // Refuse possible leaked file descriptors
18592         if (intent != null && intent.hasFileDescriptors() == true) {
18593             throw new IllegalArgumentException("File descriptors passed in Intent");
18594         }
18595
18596         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18597                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18598
18599         synchronized(this) {
18600             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18601                     != PackageManager.PERMISSION_GRANTED) {
18602                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18603                         + Binder.getCallingPid()
18604                         + ", uid=" + Binder.getCallingUid()
18605                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18606                 Slog.w(TAG, msg);
18607                 throw new SecurityException(msg);
18608             }
18609             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18610             if (stickies != null) {
18611                 ArrayList<Intent> list = stickies.get(intent.getAction());
18612                 if (list != null) {
18613                     int N = list.size();
18614                     int i;
18615                     for (i=0; i<N; i++) {
18616                         if (intent.filterEquals(list.get(i))) {
18617                             list.remove(i);
18618                             break;
18619                         }
18620                     }
18621                     if (list.size() <= 0) {
18622                         stickies.remove(intent.getAction());
18623                     }
18624                 }
18625                 if (stickies.size() <= 0) {
18626                     mStickyBroadcasts.remove(userId);
18627                 }
18628             }
18629         }
18630     }
18631
18632     void backgroundServicesFinishedLocked(int userId) {
18633         for (BroadcastQueue queue : mBroadcastQueues) {
18634             queue.backgroundServicesFinishedLocked(userId);
18635         }
18636     }
18637
18638     public void finishReceiver(IBinder who, int resultCode, String resultData,
18639             Bundle resultExtras, boolean resultAbort, int flags) {
18640         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18641
18642         // Refuse possible leaked file descriptors
18643         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18644             throw new IllegalArgumentException("File descriptors passed in Bundle");
18645         }
18646
18647         final long origId = Binder.clearCallingIdentity();
18648         try {
18649             boolean doNext = false;
18650             BroadcastRecord r;
18651
18652             synchronized(this) {
18653                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18654                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18655                 r = queue.getMatchingOrderedReceiver(who);
18656                 if (r != null) {
18657                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18658                         resultData, resultExtras, resultAbort, true);
18659                 }
18660             }
18661
18662             if (doNext) {
18663                 r.queue.processNextBroadcast(false);
18664             }
18665             trimApplications();
18666         } finally {
18667             Binder.restoreCallingIdentity(origId);
18668         }
18669     }
18670
18671     // =========================================================
18672     // INSTRUMENTATION
18673     // =========================================================
18674
18675     public boolean startInstrumentation(ComponentName className,
18676             String profileFile, int flags, Bundle arguments,
18677             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18678             int userId, String abiOverride) {
18679         enforceNotIsolatedCaller("startInstrumentation");
18680         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18681                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18682         // Refuse possible leaked file descriptors
18683         if (arguments != null && arguments.hasFileDescriptors()) {
18684             throw new IllegalArgumentException("File descriptors passed in Bundle");
18685         }
18686
18687         synchronized(this) {
18688             InstrumentationInfo ii = null;
18689             ApplicationInfo ai = null;
18690             try {
18691                 ii = mContext.getPackageManager().getInstrumentationInfo(
18692                     className, STOCK_PM_FLAGS);
18693                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18694                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18695             } catch (PackageManager.NameNotFoundException e) {
18696             } catch (RemoteException e) {
18697             }
18698             if (ii == null) {
18699                 reportStartInstrumentationFailureLocked(watcher, className,
18700                         "Unable to find instrumentation info for: " + className);
18701                 return false;
18702             }
18703             if (ai == null) {
18704                 reportStartInstrumentationFailureLocked(watcher, className,
18705                         "Unable to find instrumentation target package: " + ii.targetPackage);
18706                 return false;
18707             }
18708             if (!ai.hasCode()) {
18709                 reportStartInstrumentationFailureLocked(watcher, className,
18710                         "Instrumentation target has no code: " + ii.targetPackage);
18711                 return false;
18712             }
18713
18714             int match = mContext.getPackageManager().checkSignatures(
18715                     ii.targetPackage, ii.packageName);
18716             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18717                 String msg = "Permission Denial: starting instrumentation "
18718                         + className + " from pid="
18719                         + Binder.getCallingPid()
18720                         + ", uid=" + Binder.getCallingPid()
18721                         + " not allowed because package " + ii.packageName
18722                         + " does not have a signature matching the target "
18723                         + ii.targetPackage;
18724                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18725                 throw new SecurityException(msg);
18726             }
18727
18728             final long origId = Binder.clearCallingIdentity();
18729             // Instrumentation can kill and relaunch even persistent processes
18730             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18731                     "start instr");
18732             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18733             app.instrumentationClass = className;
18734             app.instrumentationInfo = ai;
18735             app.instrumentationProfileFile = profileFile;
18736             app.instrumentationArguments = arguments;
18737             app.instrumentationWatcher = watcher;
18738             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18739             app.instrumentationResultClass = className;
18740             Binder.restoreCallingIdentity(origId);
18741         }
18742
18743         return true;
18744     }
18745
18746     /**
18747      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18748      * error to the logs, but if somebody is watching, send the report there too.  This enables
18749      * the "am" command to report errors with more information.
18750      *
18751      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18752      * @param cn The component name of the instrumentation.
18753      * @param report The error report.
18754      */
18755     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18756             ComponentName cn, String report) {
18757         Slog.w(TAG, report);
18758         if (watcher != null) {
18759             Bundle results = new Bundle();
18760             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18761             results.putString("Error", report);
18762             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18763         }
18764     }
18765
18766     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18767         if (app.instrumentationWatcher != null) {
18768             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18769                     app.instrumentationClass, resultCode, results);
18770         }
18771
18772         // Can't call out of the system process with a lock held, so post a message.
18773         if (app.instrumentationUiAutomationConnection != null) {
18774             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18775                     app.instrumentationUiAutomationConnection).sendToTarget();
18776         }
18777
18778         app.instrumentationWatcher = null;
18779         app.instrumentationUiAutomationConnection = null;
18780         app.instrumentationClass = null;
18781         app.instrumentationInfo = null;
18782         app.instrumentationProfileFile = null;
18783         app.instrumentationArguments = null;
18784
18785         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18786                 "finished inst");
18787     }
18788
18789     public void finishInstrumentation(IApplicationThread target,
18790             int resultCode, Bundle results) {
18791         int userId = UserHandle.getCallingUserId();
18792         // Refuse possible leaked file descriptors
18793         if (results != null && results.hasFileDescriptors()) {
18794             throw new IllegalArgumentException("File descriptors passed in Intent");
18795         }
18796
18797         synchronized(this) {
18798             ProcessRecord app = getRecordForAppLocked(target);
18799             if (app == null) {
18800                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18801                 return;
18802             }
18803             final long origId = Binder.clearCallingIdentity();
18804             finishInstrumentationLocked(app, resultCode, results);
18805             Binder.restoreCallingIdentity(origId);
18806         }
18807     }
18808
18809     // =========================================================
18810     // CONFIGURATION
18811     // =========================================================
18812
18813     public ConfigurationInfo getDeviceConfigurationInfo() {
18814         ConfigurationInfo config = new ConfigurationInfo();
18815         synchronized (this) {
18816             config.reqTouchScreen = mConfiguration.touchscreen;
18817             config.reqKeyboardType = mConfiguration.keyboard;
18818             config.reqNavigation = mConfiguration.navigation;
18819             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18820                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18821                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18822             }
18823             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18824                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18825                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18826             }
18827             config.reqGlEsVersion = GL_ES_VERSION;
18828         }
18829         return config;
18830     }
18831
18832     ActivityStack getFocusedStack() {
18833         return mStackSupervisor.getFocusedStack();
18834     }
18835
18836     @Override
18837     public int getFocusedStackId() throws RemoteException {
18838         ActivityStack focusedStack = getFocusedStack();
18839         if (focusedStack != null) {
18840             return focusedStack.getStackId();
18841         }
18842         return -1;
18843     }
18844
18845     public Configuration getConfiguration() {
18846         Configuration ci;
18847         synchronized(this) {
18848             ci = new Configuration(mConfiguration);
18849             ci.userSetLocale = false;
18850         }
18851         return ci;
18852     }
18853
18854     @Override
18855     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18856         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18857         synchronized (this) {
18858             mSuppressResizeConfigChanges = suppress;
18859         }
18860     }
18861
18862     @Override
18863     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18864         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18865         if (fromStackId == HOME_STACK_ID) {
18866             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18867         }
18868         synchronized (this) {
18869             final long origId = Binder.clearCallingIdentity();
18870             try {
18871                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18872             } finally {
18873                 Binder.restoreCallingIdentity(origId);
18874             }
18875         }
18876     }
18877
18878     @Override
18879     public void updatePersistentConfiguration(Configuration values) {
18880         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18881                 "updateConfiguration()");
18882         enforceWriteSettingsPermission("updateConfiguration()");
18883         if (values == null) {
18884             throw new NullPointerException("Configuration must not be null");
18885         }
18886
18887         int userId = UserHandle.getCallingUserId();
18888
18889         synchronized(this) {
18890             updatePersistentConfigurationLocked(values, userId);
18891         }
18892     }
18893
18894     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18895         final long origId = Binder.clearCallingIdentity();
18896         try {
18897             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18898         } finally {
18899             Binder.restoreCallingIdentity(origId);
18900         }
18901     }
18902
18903     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18904         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18905                 FONT_SCALE, 1.0f, userId);
18906         if (mConfiguration.fontScale != scaleFactor) {
18907             final Configuration configuration = mWindowManager.computeNewConfiguration();
18908             configuration.fontScale = scaleFactor;
18909             synchronized (this) {
18910                 updatePersistentConfigurationLocked(configuration, userId);
18911             }
18912         }
18913     }
18914
18915     private void enforceWriteSettingsPermission(String func) {
18916         int uid = Binder.getCallingUid();
18917         if (uid == Process.ROOT_UID) {
18918             return;
18919         }
18920
18921         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18922                 Settings.getPackageNameForUid(mContext, uid), false)) {
18923             return;
18924         }
18925
18926         String msg = "Permission Denial: " + func + " from pid="
18927                 + Binder.getCallingPid()
18928                 + ", uid=" + uid
18929                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18930         Slog.w(TAG, msg);
18931         throw new SecurityException(msg);
18932     }
18933
18934     public void updateConfiguration(Configuration values) {
18935         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18936                 "updateConfiguration()");
18937
18938         synchronized(this) {
18939             if (values == null && mWindowManager != null) {
18940                 // sentinel: fetch the current configuration from the window manager
18941                 values = mWindowManager.computeNewConfiguration();
18942             }
18943
18944             if (mWindowManager != null) {
18945                 mProcessList.applyDisplaySize(mWindowManager);
18946             }
18947
18948             final long origId = Binder.clearCallingIdentity();
18949             if (values != null) {
18950                 Settings.System.clearConfiguration(values);
18951             }
18952             updateConfigurationLocked(values, null, false);
18953             Binder.restoreCallingIdentity(origId);
18954         }
18955     }
18956
18957     void updateUserConfigurationLocked() {
18958         Configuration configuration = new Configuration(mConfiguration);
18959         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18960                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18961         updateConfigurationLocked(configuration, null, false);
18962     }
18963
18964     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18965             boolean initLocale) {
18966         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18967     }
18968
18969     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18970             boolean initLocale, boolean deferResume) {
18971         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18972         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18973                 UserHandle.USER_NULL, deferResume);
18974     }
18975
18976     // To cache the list of supported system locales
18977     private String[] mSupportedSystemLocales = null;
18978
18979     /**
18980      * Do either or both things: (1) change the current configuration, and (2)
18981      * make sure the given activity is running with the (now) current
18982      * configuration.  Returns true if the activity has been left running, or
18983      * false if <var>starting</var> is being destroyed to match the new
18984      * configuration.
18985      *
18986      * @param userId is only used when persistent parameter is set to true to persist configuration
18987      *               for that particular user
18988      */
18989     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18990             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18991         int changes = 0;
18992
18993         if (mWindowManager != null) {
18994             mWindowManager.deferSurfaceLayout();
18995         }
18996         if (values != null) {
18997             Configuration newConfig = new Configuration(mConfiguration);
18998             changes = newConfig.updateFrom(values);
18999             if (changes != 0) {
19000                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19001                         "Updating configuration to: " + values);
19002
19003                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19004
19005                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19006                     final LocaleList locales = values.getLocales();
19007                     int bestLocaleIndex = 0;
19008                     if (locales.size() > 1) {
19009                         if (mSupportedSystemLocales == null) {
19010                             mSupportedSystemLocales =
19011                                     Resources.getSystem().getAssets().getLocales();
19012                         }
19013                         bestLocaleIndex = Math.max(0,
19014                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
19015                     }
19016                     SystemProperties.set("persist.sys.locale",
19017                             locales.get(bestLocaleIndex).toLanguageTag());
19018                     LocaleList.setDefault(locales, bestLocaleIndex);
19019                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19020                             locales.get(bestLocaleIndex)));
19021                 }
19022
19023                 mConfigurationSeq++;
19024                 if (mConfigurationSeq <= 0) {
19025                     mConfigurationSeq = 1;
19026                 }
19027                 newConfig.seq = mConfigurationSeq;
19028                 mConfiguration = newConfig;
19029                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19030                 mUsageStatsService.reportConfigurationChange(newConfig,
19031                         mUserController.getCurrentUserIdLocked());
19032                 //mUsageStatsService.noteStartConfig(newConfig);
19033
19034                 final Configuration configCopy = new Configuration(mConfiguration);
19035
19036                 // TODO: If our config changes, should we auto dismiss any currently
19037                 // showing dialogs?
19038                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19039
19040                 AttributeCache ac = AttributeCache.instance();
19041                 if (ac != null) {
19042                     ac.updateConfiguration(configCopy);
19043                 }
19044
19045                 // Make sure all resources in our process are updated
19046                 // right now, so that anyone who is going to retrieve
19047                 // resource values after we return will be sure to get
19048                 // the new ones.  This is especially important during
19049                 // boot, where the first config change needs to guarantee
19050                 // all resources have that config before following boot
19051                 // code is executed.
19052                 mSystemThread.applyConfigurationToResources(configCopy);
19053
19054                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19055                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19056                     msg.obj = new Configuration(configCopy);
19057                     msg.arg1 = userId;
19058                     mHandler.sendMessage(msg);
19059                 }
19060
19061                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19062                 if (isDensityChange) {
19063                     // Reset the unsupported display size dialog.
19064                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19065
19066                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19067                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19068                 }
19069
19070                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19071                     ProcessRecord app = mLruProcesses.get(i);
19072                     try {
19073                         if (app.thread != null) {
19074                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19075                                     + app.processName + " new config " + mConfiguration);
19076                             app.thread.scheduleConfigurationChanged(configCopy);
19077                         }
19078                     } catch (Exception e) {
19079                     }
19080                 }
19081                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19082                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19083                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19084                         | Intent.FLAG_RECEIVER_FOREGROUND);
19085                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19086                         null, AppOpsManager.OP_NONE, null, false, false,
19087                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19088                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19089                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19090                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19091                     if (!mProcessesReady) {
19092                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19093                     }
19094                     broadcastIntentLocked(null, null, intent,
19095                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19096                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19097                 }
19098             }
19099             // Update the configuration with WM first and check if any of the stacks need to be
19100             // resized due to the configuration change. If so, resize the stacks now and do any
19101             // relaunches if necessary. This way we don't need to relaunch again below in
19102             // ensureActivityConfigurationLocked().
19103             if (mWindowManager != null) {
19104                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19105                 if (resizedStacks != null) {
19106                     for (int stackId : resizedStacks) {
19107                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19108                         mStackSupervisor.resizeStackLocked(
19109                                 stackId, newBounds, null, null, false, false, deferResume);
19110                     }
19111                 }
19112             }
19113         }
19114
19115         boolean kept = true;
19116         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19117         // mainStack is null during startup.
19118         if (mainStack != null) {
19119             if (changes != 0 && starting == null) {
19120                 // If the configuration changed, and the caller is not already
19121                 // in the process of starting an activity, then find the top
19122                 // activity to check if its configuration needs to change.
19123                 starting = mainStack.topRunningActivityLocked();
19124             }
19125
19126             if (starting != null) {
19127                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19128                 // And we need to make sure at this point that all other activities
19129                 // are made visible with the correct configuration.
19130                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19131                         !PRESERVE_WINDOWS);
19132             }
19133         }
19134         if (mWindowManager != null) {
19135             mWindowManager.continueSurfaceLayout();
19136         }
19137         return kept;
19138     }
19139
19140     /**
19141      * Decide based on the configuration whether we should shouw the ANR,
19142      * crash, etc dialogs.  The idea is that if there is no affordence to
19143      * press the on-screen buttons, or the user experience would be more
19144      * greatly impacted than the crash itself, we shouldn't show the dialog.
19145      *
19146      * A thought: SystemUI might also want to get told about this, the Power
19147      * dialog / global actions also might want different behaviors.
19148      */
19149     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19150         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19151                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19152                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19153         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19154         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19155                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19156         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19157     }
19158
19159     @Override
19160     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19161         synchronized (this) {
19162             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19163             if (srec != null) {
19164                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19165             }
19166         }
19167         return false;
19168     }
19169
19170     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19171             Intent resultData) {
19172
19173         synchronized (this) {
19174             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19175             if (r != null) {
19176                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19177             }
19178             return false;
19179         }
19180     }
19181
19182     public int getLaunchedFromUid(IBinder activityToken) {
19183         ActivityRecord srec;
19184         synchronized (this) {
19185             srec = ActivityRecord.forTokenLocked(activityToken);
19186         }
19187         if (srec == null) {
19188             return -1;
19189         }
19190         return srec.launchedFromUid;
19191     }
19192
19193     public String getLaunchedFromPackage(IBinder activityToken) {
19194         ActivityRecord srec;
19195         synchronized (this) {
19196             srec = ActivityRecord.forTokenLocked(activityToken);
19197         }
19198         if (srec == null) {
19199             return null;
19200         }
19201         return srec.launchedFromPackage;
19202     }
19203
19204     // =========================================================
19205     // LIFETIME MANAGEMENT
19206     // =========================================================
19207
19208     // Returns which broadcast queue the app is the current [or imminent] receiver
19209     // on, or 'null' if the app is not an active broadcast recipient.
19210     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19211         BroadcastRecord r = app.curReceiver;
19212         if (r != null) {
19213             return r.queue;
19214         }
19215
19216         // It's not the current receiver, but it might be starting up to become one
19217         synchronized (this) {
19218             for (BroadcastQueue queue : mBroadcastQueues) {
19219                 r = queue.mPendingBroadcast;
19220                 if (r != null && r.curApp == app) {
19221                     // found it; report which queue it's in
19222                     return queue;
19223                 }
19224             }
19225         }
19226
19227         return null;
19228     }
19229
19230     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19231             int targetUid, ComponentName targetComponent, String targetProcess) {
19232         if (!mTrackingAssociations) {
19233             return null;
19234         }
19235         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19236                 = mAssociations.get(targetUid);
19237         if (components == null) {
19238             components = new ArrayMap<>();
19239             mAssociations.put(targetUid, components);
19240         }
19241         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19242         if (sourceUids == null) {
19243             sourceUids = new SparseArray<>();
19244             components.put(targetComponent, sourceUids);
19245         }
19246         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19247         if (sourceProcesses == null) {
19248             sourceProcesses = new ArrayMap<>();
19249             sourceUids.put(sourceUid, sourceProcesses);
19250         }
19251         Association ass = sourceProcesses.get(sourceProcess);
19252         if (ass == null) {
19253             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19254                     targetProcess);
19255             sourceProcesses.put(sourceProcess, ass);
19256         }
19257         ass.mCount++;
19258         ass.mNesting++;
19259         if (ass.mNesting == 1) {
19260             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19261             ass.mLastState = sourceState;
19262         }
19263         return ass;
19264     }
19265
19266     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19267             ComponentName targetComponent) {
19268         if (!mTrackingAssociations) {
19269             return;
19270         }
19271         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19272                 = mAssociations.get(targetUid);
19273         if (components == null) {
19274             return;
19275         }
19276         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19277         if (sourceUids == null) {
19278             return;
19279         }
19280         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19281         if (sourceProcesses == null) {
19282             return;
19283         }
19284         Association ass = sourceProcesses.get(sourceProcess);
19285         if (ass == null || ass.mNesting <= 0) {
19286             return;
19287         }
19288         ass.mNesting--;
19289         if (ass.mNesting == 0) {
19290             long uptime = SystemClock.uptimeMillis();
19291             ass.mTime += uptime - ass.mStartTime;
19292             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19293                     += uptime - ass.mLastStateUptime;
19294             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19295         }
19296     }
19297
19298     private void noteUidProcessState(final int uid, final int state) {
19299         mBatteryStatsService.noteUidProcessState(uid, state);
19300         if (mTrackingAssociations) {
19301             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19302                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19303                         = mAssociations.valueAt(i1);
19304                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19305                     SparseArray<ArrayMap<String, Association>> sourceUids
19306                             = targetComponents.valueAt(i2);
19307                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19308                     if (sourceProcesses != null) {
19309                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19310                             Association ass = sourceProcesses.valueAt(i4);
19311                             if (ass.mNesting >= 1) {
19312                                 // currently associated
19313                                 long uptime = SystemClock.uptimeMillis();
19314                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19315                                         += uptime - ass.mLastStateUptime;
19316                                 ass.mLastState = state;
19317                                 ass.mLastStateUptime = uptime;
19318                             }
19319                         }
19320                     }
19321                 }
19322             }
19323         }
19324     }
19325
19326     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19327             boolean doingAll, long now) {
19328         if (mAdjSeq == app.adjSeq) {
19329             // This adjustment has already been computed.
19330             return app.curRawAdj;
19331         }
19332
19333         if (app.thread == null) {
19334             app.adjSeq = mAdjSeq;
19335             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19336             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19337             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19338         }
19339
19340         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19341         app.adjSource = null;
19342         app.adjTarget = null;
19343         app.empty = false;
19344         app.cached = false;
19345
19346         final int activitiesSize = app.activities.size();
19347
19348         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19349             // The max adjustment doesn't allow this app to be anything
19350             // below foreground, so it is not worth doing work for it.
19351             app.adjType = "fixed";
19352             app.adjSeq = mAdjSeq;
19353             app.curRawAdj = app.maxAdj;
19354             app.foregroundActivities = false;
19355             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19356             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19357             // System processes can do UI, and when they do we want to have
19358             // them trim their memory after the user leaves the UI.  To
19359             // facilitate this, here we need to determine whether or not it
19360             // is currently showing UI.
19361             app.systemNoUi = true;
19362             if (app == TOP_APP) {
19363                 app.systemNoUi = false;
19364                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19365                 app.adjType = "pers-top-activity";
19366             } else if (app.hasTopUi) {
19367                 app.systemNoUi = false;
19368                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19369                 app.adjType = "pers-top-ui";
19370             } else if (activitiesSize > 0) {
19371                 for (int j = 0; j < activitiesSize; j++) {
19372                     final ActivityRecord r = app.activities.get(j);
19373                     if (r.visible) {
19374                         app.systemNoUi = false;
19375                     }
19376                 }
19377             }
19378             if (!app.systemNoUi) {
19379                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19380             }
19381             return (app.curAdj=app.maxAdj);
19382         }
19383
19384         app.systemNoUi = false;
19385
19386         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19387
19388         // Determine the importance of the process, starting with most
19389         // important to least, and assign an appropriate OOM adjustment.
19390         int adj;
19391         int schedGroup;
19392         int procState;
19393         boolean foregroundActivities = false;
19394         BroadcastQueue queue;
19395         if (app == TOP_APP) {
19396             // The last app on the list is the foreground app.
19397             adj = ProcessList.FOREGROUND_APP_ADJ;
19398             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19399             app.adjType = "top-activity";
19400             foregroundActivities = true;
19401             procState = PROCESS_STATE_CUR_TOP;
19402         } else if (app.instrumentationClass != null) {
19403             // Don't want to kill running instrumentation.
19404             adj = ProcessList.FOREGROUND_APP_ADJ;
19405             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19406             app.adjType = "instrumentation";
19407             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19408         } else if ((queue = isReceivingBroadcast(app)) != null) {
19409             // An app that is currently receiving a broadcast also
19410             // counts as being in the foreground for OOM killer purposes.
19411             // It's placed in a sched group based on the nature of the
19412             // broadcast as reflected by which queue it's active in.
19413             adj = ProcessList.FOREGROUND_APP_ADJ;
19414             schedGroup = (queue == mFgBroadcastQueue)
19415                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19416             app.adjType = "broadcast";
19417             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19418         } else if (app.executingServices.size() > 0) {
19419             // An app that is currently executing a service callback also
19420             // counts as being in the foreground.
19421             adj = ProcessList.FOREGROUND_APP_ADJ;
19422             schedGroup = app.execServicesFg ?
19423                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19424             app.adjType = "exec-service";
19425             procState = ActivityManager.PROCESS_STATE_SERVICE;
19426             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19427         } else {
19428             // As far as we know the process is empty.  We may change our mind later.
19429             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19430             // At this point we don't actually know the adjustment.  Use the cached adj
19431             // value that the caller wants us to.
19432             adj = cachedAdj;
19433             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19434             app.cached = true;
19435             app.empty = true;
19436             app.adjType = "cch-empty";
19437         }
19438
19439         // Examine all activities if not already foreground.
19440         if (!foregroundActivities && activitiesSize > 0) {
19441             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19442             for (int j = 0; j < activitiesSize; j++) {
19443                 final ActivityRecord r = app.activities.get(j);
19444                 if (r.app != app) {
19445                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19446                             + " instead of expected " + app);
19447                     if (r.app == null || (r.app.uid == app.uid)) {
19448                         // Only fix things up when they look sane
19449                         r.app = app;
19450                     } else {
19451                         continue;
19452                     }
19453                 }
19454                 if (r.visible) {
19455                     // App has a visible activity; only upgrade adjustment.
19456                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19457                         adj = ProcessList.VISIBLE_APP_ADJ;
19458                         app.adjType = "visible";
19459                     }
19460                     if (procState > PROCESS_STATE_CUR_TOP) {
19461                         procState = PROCESS_STATE_CUR_TOP;
19462                     }
19463                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19464                     app.cached = false;
19465                     app.empty = false;
19466                     foregroundActivities = true;
19467                     if (r.task != null && minLayer > 0) {
19468                         final int layer = r.task.mLayerRank;
19469                         if (layer >= 0 && minLayer > layer) {
19470                             minLayer = layer;
19471                         }
19472                     }
19473                     break;
19474                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19475                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19476                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19477                         app.adjType = "pausing";
19478                     }
19479                     if (procState > PROCESS_STATE_CUR_TOP) {
19480                         procState = PROCESS_STATE_CUR_TOP;
19481                     }
19482                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19483                     app.cached = false;
19484                     app.empty = false;
19485                     foregroundActivities = true;
19486                 } else if (r.state == ActivityState.STOPPING) {
19487                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19488                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19489                         app.adjType = "stopping";
19490                     }
19491                     // For the process state, we will at this point consider the
19492                     // process to be cached.  It will be cached either as an activity
19493                     // or empty depending on whether the activity is finishing.  We do
19494                     // this so that we can treat the process as cached for purposes of
19495                     // memory trimming (determing current memory level, trim command to
19496                     // send to process) since there can be an arbitrary number of stopping
19497                     // processes and they should soon all go into the cached state.
19498                     if (!r.finishing) {
19499                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19500                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19501                         }
19502                     }
19503                     app.cached = false;
19504                     app.empty = false;
19505                     foregroundActivities = true;
19506                 } else {
19507                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19508                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19509                         app.adjType = "cch-act";
19510                     }
19511                 }
19512             }
19513             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19514                 adj += minLayer;
19515             }
19516         }
19517
19518         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19519                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19520             if (app.foregroundServices) {
19521                 // The user is aware of this app, so make it visible.
19522                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19523                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19524                 app.cached = false;
19525                 app.adjType = "fg-service";
19526                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19527             } else if (app.forcingToForeground != null) {
19528                 // The user is aware of this app, so make it visible.
19529                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19530                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19531                 app.cached = false;
19532                 app.adjType = "force-fg";
19533                 app.adjSource = app.forcingToForeground;
19534                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19535             }
19536         }
19537
19538         if (app == mHeavyWeightProcess) {
19539             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19540                 // We don't want to kill the current heavy-weight process.
19541                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19542                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19543                 app.cached = false;
19544                 app.adjType = "heavy";
19545             }
19546             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19547                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19548             }
19549         }
19550
19551         if (app == mHomeProcess) {
19552             if (adj > ProcessList.HOME_APP_ADJ) {
19553                 // This process is hosting what we currently consider to be the
19554                 // home app, so we don't want to let it go into the background.
19555                 adj = ProcessList.HOME_APP_ADJ;
19556                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19557                 app.cached = false;
19558                 app.adjType = "home";
19559             }
19560             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19561                 procState = ActivityManager.PROCESS_STATE_HOME;
19562             }
19563         }
19564
19565         if (app == mPreviousProcess && app.activities.size() > 0) {
19566             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19567                 // This was the previous process that showed UI to the user.
19568                 // We want to try to keep it around more aggressively, to give
19569                 // a good experience around switching between two apps.
19570                 adj = ProcessList.PREVIOUS_APP_ADJ;
19571                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19572                 app.cached = false;
19573                 app.adjType = "previous";
19574             }
19575             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19576                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19577             }
19578         }
19579
19580         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19581                 + " reason=" + app.adjType);
19582
19583         // By default, we use the computed adjustment.  It may be changed if
19584         // there are applications dependent on our services or providers, but
19585         // this gives us a baseline and makes sure we don't get into an
19586         // infinite recursion.
19587         app.adjSeq = mAdjSeq;
19588         app.curRawAdj = adj;
19589         app.hasStartedServices = false;
19590
19591         if (mBackupTarget != null && app == mBackupTarget.app) {
19592             // If possible we want to avoid killing apps while they're being backed up
19593             if (adj > ProcessList.BACKUP_APP_ADJ) {
19594                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19595                 adj = ProcessList.BACKUP_APP_ADJ;
19596                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19597                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19598                 }
19599                 app.adjType = "backup";
19600                 app.cached = false;
19601             }
19602             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19603                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19604             }
19605         }
19606
19607         boolean mayBeTop = false;
19608
19609         for (int is = app.services.size()-1;
19610                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19611                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19612                         || procState > ActivityManager.PROCESS_STATE_TOP);
19613                 is--) {
19614             ServiceRecord s = app.services.valueAt(is);
19615             if (s.startRequested) {
19616                 app.hasStartedServices = true;
19617                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19618                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19619                 }
19620                 if (app.hasShownUi && app != mHomeProcess) {
19621                     // If this process has shown some UI, let it immediately
19622                     // go to the LRU list because it may be pretty heavy with
19623                     // UI stuff.  We'll tag it with a label just to help
19624                     // debug and understand what is going on.
19625                     if (adj > ProcessList.SERVICE_ADJ) {
19626                         app.adjType = "cch-started-ui-services";
19627                     }
19628                 } else {
19629                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19630                         // This service has seen some activity within
19631                         // recent memory, so we will keep its process ahead
19632                         // of the background processes.
19633                         if (adj > ProcessList.SERVICE_ADJ) {
19634                             adj = ProcessList.SERVICE_ADJ;
19635                             app.adjType = "started-services";
19636                             app.cached = false;
19637                         }
19638                     }
19639                     // If we have let the service slide into the background
19640                     // state, still have some text describing what it is doing
19641                     // even though the service no longer has an impact.
19642                     if (adj > ProcessList.SERVICE_ADJ) {
19643                         app.adjType = "cch-started-services";
19644                     }
19645                 }
19646             }
19647
19648             for (int conni = s.connections.size()-1;
19649                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19650                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19651                             || procState > ActivityManager.PROCESS_STATE_TOP);
19652                     conni--) {
19653                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19654                 for (int i = 0;
19655                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19656                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19657                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19658                         i++) {
19659                     // XXX should compute this based on the max of
19660                     // all connected clients.
19661                     ConnectionRecord cr = clist.get(i);
19662                     if (cr.binding.client == app) {
19663                         // Binding to ourself is not interesting.
19664                         continue;
19665                     }
19666
19667                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19668                         ProcessRecord client = cr.binding.client;
19669                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19670                                 TOP_APP, doingAll, now);
19671                         int clientProcState = client.curProcState;
19672                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19673                             // If the other app is cached for any reason, for purposes here
19674                             // we are going to consider it empty.  The specific cached state
19675                             // doesn't propagate except under certain conditions.
19676                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19677                         }
19678                         String adjType = null;
19679                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19680                             // Not doing bind OOM management, so treat
19681                             // this guy more like a started service.
19682                             if (app.hasShownUi && app != mHomeProcess) {
19683                                 // If this process has shown some UI, let it immediately
19684                                 // go to the LRU list because it may be pretty heavy with
19685                                 // UI stuff.  We'll tag it with a label just to help
19686                                 // debug and understand what is going on.
19687                                 if (adj > clientAdj) {
19688                                     adjType = "cch-bound-ui-services";
19689                                 }
19690                                 app.cached = false;
19691                                 clientAdj = adj;
19692                                 clientProcState = procState;
19693                             } else {
19694                                 if (now >= (s.lastActivity
19695                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19696                                     // This service has not seen activity within
19697                                     // recent memory, so allow it to drop to the
19698                                     // LRU list if there is no other reason to keep
19699                                     // it around.  We'll also tag it with a label just
19700                                     // to help debug and undertand what is going on.
19701                                     if (adj > clientAdj) {
19702                                         adjType = "cch-bound-services";
19703                                     }
19704                                     clientAdj = adj;
19705                                 }
19706                             }
19707                         }
19708                         if (adj > clientAdj) {
19709                             // If this process has recently shown UI, and
19710                             // the process that is binding to it is less
19711                             // important than being visible, then we don't
19712                             // care about the binding as much as we care
19713                             // about letting this process get into the LRU
19714                             // list to be killed and restarted if needed for
19715                             // memory.
19716                             if (app.hasShownUi && app != mHomeProcess
19717                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19718                                 adjType = "cch-bound-ui-services";
19719                             } else {
19720                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19721                                         |Context.BIND_IMPORTANT)) != 0) {
19722                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19723                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19724                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19725                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19726                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19727                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19728                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19729                                     adj = clientAdj;
19730                                 } else {
19731                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19732                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19733                                     }
19734                                 }
19735                                 if (!client.cached) {
19736                                     app.cached = false;
19737                                 }
19738                                 adjType = "service";
19739                             }
19740                         }
19741                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19742                             // This will treat important bound services identically to
19743                             // the top app, which may behave differently than generic
19744                             // foreground work.
19745                             if (client.curSchedGroup > schedGroup) {
19746                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19747                                     schedGroup = client.curSchedGroup;
19748                                 } else {
19749                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19750                                 }
19751                             }
19752                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19753                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19754                                     // Special handling of clients who are in the top state.
19755                                     // We *may* want to consider this process to be in the
19756                                     // top state as well, but only if there is not another
19757                                     // reason for it to be running.  Being on the top is a
19758                                     // special state, meaning you are specifically running
19759                                     // for the current top app.  If the process is already
19760                                     // running in the background for some other reason, it
19761                                     // is more important to continue considering it to be
19762                                     // in the background state.
19763                                     mayBeTop = true;
19764                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19765                                 } else {
19766                                     // Special handling for above-top states (persistent
19767                                     // processes).  These should not bring the current process
19768                                     // into the top state, since they are not on top.  Instead
19769                                     // give them the best state after that.
19770                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19771                                         clientProcState =
19772                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19773                                     } else if (mWakefulness
19774                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19775                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19776                                                     != 0) {
19777                                         clientProcState =
19778                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19779                                     } else {
19780                                         clientProcState =
19781                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19782                                     }
19783                                 }
19784                             }
19785                         } else {
19786                             if (clientProcState <
19787                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19788                                 clientProcState =
19789                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19790                             }
19791                         }
19792                         if (procState > clientProcState) {
19793                             procState = clientProcState;
19794                         }
19795                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19796                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19797                             app.pendingUiClean = true;
19798                         }
19799                         if (adjType != null) {
19800                             app.adjType = adjType;
19801                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19802                                     .REASON_SERVICE_IN_USE;
19803                             app.adjSource = cr.binding.client;
19804                             app.adjSourceProcState = clientProcState;
19805                             app.adjTarget = s.name;
19806                         }
19807                     }
19808                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19809                         app.treatLikeActivity = true;
19810                     }
19811                     final ActivityRecord a = cr.activity;
19812                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19813                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19814                             (a.visible || a.state == ActivityState.RESUMED ||
19815                              a.state == ActivityState.PAUSING)) {
19816                             adj = ProcessList.FOREGROUND_APP_ADJ;
19817                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19818                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19819                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19820                                 } else {
19821                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19822                                 }
19823                             }
19824                             app.cached = false;
19825                             app.adjType = "service";
19826                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19827                                     .REASON_SERVICE_IN_USE;
19828                             app.adjSource = a;
19829                             app.adjSourceProcState = procState;
19830                             app.adjTarget = s.name;
19831                         }
19832                     }
19833                 }
19834             }
19835         }
19836
19837         for (int provi = app.pubProviders.size()-1;
19838                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19839                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19840                         || procState > ActivityManager.PROCESS_STATE_TOP);
19841                 provi--) {
19842             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19843             for (int i = cpr.connections.size()-1;
19844                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19845                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19846                             || procState > ActivityManager.PROCESS_STATE_TOP);
19847                     i--) {
19848                 ContentProviderConnection conn = cpr.connections.get(i);
19849                 ProcessRecord client = conn.client;
19850                 if (client == app) {
19851                     // Being our own client is not interesting.
19852                     continue;
19853                 }
19854                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19855                 int clientProcState = client.curProcState;
19856                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19857                     // If the other app is cached for any reason, for purposes here
19858                     // we are going to consider it empty.
19859                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19860                 }
19861                 if (adj > clientAdj) {
19862                     if (app.hasShownUi && app != mHomeProcess
19863                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19864                         app.adjType = "cch-ui-provider";
19865                     } else {
19866                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19867                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19868                         app.adjType = "provider";
19869                     }
19870                     app.cached &= client.cached;
19871                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19872                             .REASON_PROVIDER_IN_USE;
19873                     app.adjSource = client;
19874                     app.adjSourceProcState = clientProcState;
19875                     app.adjTarget = cpr.name;
19876                 }
19877                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19878                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19879                         // Special handling of clients who are in the top state.
19880                         // We *may* want to consider this process to be in the
19881                         // top state as well, but only if there is not another
19882                         // reason for it to be running.  Being on the top is a
19883                         // special state, meaning you are specifically running
19884                         // for the current top app.  If the process is already
19885                         // running in the background for some other reason, it
19886                         // is more important to continue considering it to be
19887                         // in the background state.
19888                         mayBeTop = true;
19889                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19890                     } else {
19891                         // Special handling for above-top states (persistent
19892                         // processes).  These should not bring the current process
19893                         // into the top state, since they are not on top.  Instead
19894                         // give them the best state after that.
19895                         clientProcState =
19896                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19897                     }
19898                 }
19899                 if (procState > clientProcState) {
19900                     procState = clientProcState;
19901                 }
19902                 if (client.curSchedGroup > schedGroup) {
19903                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19904                 }
19905             }
19906             // If the provider has external (non-framework) process
19907             // dependencies, ensure that its adjustment is at least
19908             // FOREGROUND_APP_ADJ.
19909             if (cpr.hasExternalProcessHandles()) {
19910                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19911                     adj = ProcessList.FOREGROUND_APP_ADJ;
19912                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19913                     app.cached = false;
19914                     app.adjType = "provider";
19915                     app.adjTarget = cpr.name;
19916                 }
19917                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19918                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19919                 }
19920             }
19921         }
19922
19923         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19924             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19925                 adj = ProcessList.PREVIOUS_APP_ADJ;
19926                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19927                 app.cached = false;
19928                 app.adjType = "provider";
19929             }
19930             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19931                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19932             }
19933         }
19934
19935         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19936             // A client of one of our services or providers is in the top state.  We
19937             // *may* want to be in the top state, but not if we are already running in
19938             // the background for some other reason.  For the decision here, we are going
19939             // to pick out a few specific states that we want to remain in when a client
19940             // is top (states that tend to be longer-term) and otherwise allow it to go
19941             // to the top state.
19942             switch (procState) {
19943                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19944                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19945                 case ActivityManager.PROCESS_STATE_SERVICE:
19946                     // These all are longer-term states, so pull them up to the top
19947                     // of the background states, but not all the way to the top state.
19948                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19949                     break;
19950                 default:
19951                     // Otherwise, top is a better choice, so take it.
19952                     procState = ActivityManager.PROCESS_STATE_TOP;
19953                     break;
19954             }
19955         }
19956
19957         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19958             if (app.hasClientActivities) {
19959                 // This is a cached process, but with client activities.  Mark it so.
19960                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19961                 app.adjType = "cch-client-act";
19962             } else if (app.treatLikeActivity) {
19963                 // This is a cached process, but somebody wants us to treat it like it has
19964                 // an activity, okay!
19965                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19966                 app.adjType = "cch-as-act";
19967             }
19968         }
19969
19970         if (adj == ProcessList.SERVICE_ADJ) {
19971             if (doingAll) {
19972                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19973                 mNewNumServiceProcs++;
19974                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19975                 if (!app.serviceb) {
19976                     // This service isn't far enough down on the LRU list to
19977                     // normally be a B service, but if we are low on RAM and it
19978                     // is large we want to force it down since we would prefer to
19979                     // keep launcher over it.
19980                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19981                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19982                         app.serviceHighRam = true;
19983                         app.serviceb = true;
19984                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19985                     } else {
19986                         mNewNumAServiceProcs++;
19987                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19988                     }
19989                 } else {
19990                     app.serviceHighRam = false;
19991                 }
19992             }
19993             if (app.serviceb) {
19994                 adj = ProcessList.SERVICE_B_ADJ;
19995             }
19996         }
19997
19998         app.curRawAdj = adj;
19999
20000         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20001         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20002         if (adj > app.maxAdj) {
20003             adj = app.maxAdj;
20004             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20005                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20006             }
20007         }
20008
20009         // Do final modification to adj.  Everything we do between here and applying
20010         // the final setAdj must be done in this function, because we will also use
20011         // it when computing the final cached adj later.  Note that we don't need to
20012         // worry about this for max adj above, since max adj will always be used to
20013         // keep it out of the cached vaues.
20014         app.curAdj = app.modifyRawOomAdj(adj);
20015         app.curSchedGroup = schedGroup;
20016         app.curProcState = procState;
20017         app.foregroundActivities = foregroundActivities;
20018
20019         return app.curRawAdj;
20020     }
20021
20022     /**
20023      * Record new PSS sample for a process.
20024      */
20025     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20026             long now) {
20027         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20028                 swapPss * 1024);
20029         proc.lastPssTime = now;
20030         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20031         if (DEBUG_PSS) Slog.d(TAG_PSS,
20032                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20033                 + " state=" + ProcessList.makeProcStateString(procState));
20034         if (proc.initialIdlePss == 0) {
20035             proc.initialIdlePss = pss;
20036         }
20037         proc.lastPss = pss;
20038         proc.lastSwapPss = swapPss;
20039         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20040             proc.lastCachedPss = pss;
20041             proc.lastCachedSwapPss = swapPss;
20042         }
20043
20044         final SparseArray<Pair<Long, String>> watchUids
20045                 = mMemWatchProcesses.getMap().get(proc.processName);
20046         Long check = null;
20047         if (watchUids != null) {
20048             Pair<Long, String> val = watchUids.get(proc.uid);
20049             if (val == null) {
20050                 val = watchUids.get(0);
20051             }
20052             if (val != null) {
20053                 check = val.first;
20054             }
20055         }
20056         if (check != null) {
20057             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20058                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20059                 if (!isDebuggable) {
20060                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20061                         isDebuggable = true;
20062                     }
20063                 }
20064                 if (isDebuggable) {
20065                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20066                     final ProcessRecord myProc = proc;
20067                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20068                     mMemWatchDumpProcName = proc.processName;
20069                     mMemWatchDumpFile = heapdumpFile.toString();
20070                     mMemWatchDumpPid = proc.pid;
20071                     mMemWatchDumpUid = proc.uid;
20072                     BackgroundThread.getHandler().post(new Runnable() {
20073                         @Override
20074                         public void run() {
20075                             revokeUriPermission(ActivityThread.currentActivityThread()
20076                                             .getApplicationThread(),
20077                                     DumpHeapActivity.JAVA_URI,
20078                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20079                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20080                                     UserHandle.myUserId());
20081                             ParcelFileDescriptor fd = null;
20082                             try {
20083                                 heapdumpFile.delete();
20084                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20085                                         ParcelFileDescriptor.MODE_CREATE |
20086                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20087                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20088                                                 ParcelFileDescriptor.MODE_APPEND);
20089                                 IApplicationThread thread = myProc.thread;
20090                                 if (thread != null) {
20091                                     try {
20092                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20093                                                 "Requesting dump heap from "
20094                                                 + myProc + " to " + heapdumpFile);
20095                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20096                                     } catch (RemoteException e) {
20097                                     }
20098                                 }
20099                             } catch (FileNotFoundException e) {
20100                                 e.printStackTrace();
20101                             } finally {
20102                                 if (fd != null) {
20103                                     try {
20104                                         fd.close();
20105                                     } catch (IOException e) {
20106                                     }
20107                                 }
20108                             }
20109                         }
20110                     });
20111                 } else {
20112                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20113                             + ", but debugging not enabled");
20114                 }
20115             }
20116         }
20117     }
20118
20119     /**
20120      * Schedule PSS collection of a process.
20121      */
20122     void requestPssLocked(ProcessRecord proc, int procState) {
20123         if (mPendingPssProcesses.contains(proc)) {
20124             return;
20125         }
20126         if (mPendingPssProcesses.size() == 0) {
20127             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20128         }
20129         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20130         proc.pssProcState = procState;
20131         mPendingPssProcesses.add(proc);
20132     }
20133
20134     /**
20135      * Schedule PSS collection of all processes.
20136      */
20137     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20138         if (!always) {
20139             if (now < (mLastFullPssTime +
20140                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20141                 return;
20142             }
20143         }
20144         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20145         mLastFullPssTime = now;
20146         mFullPssPending = true;
20147         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20148         mPendingPssProcesses.clear();
20149         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20150             ProcessRecord app = mLruProcesses.get(i);
20151             if (app.thread == null
20152                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20153                 continue;
20154             }
20155             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20156                 app.pssProcState = app.setProcState;
20157                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20158                         mTestPssMode, isSleepingLocked(), now);
20159                 mPendingPssProcesses.add(app);
20160             }
20161         }
20162         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20163     }
20164
20165     public void setTestPssMode(boolean enabled) {
20166         synchronized (this) {
20167             mTestPssMode = enabled;
20168             if (enabled) {
20169                 // Whenever we enable the mode, we want to take a snapshot all of current
20170                 // process mem use.
20171                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20172             }
20173         }
20174     }
20175
20176     /**
20177      * Ask a given process to GC right now.
20178      */
20179     final void performAppGcLocked(ProcessRecord app) {
20180         try {
20181             app.lastRequestedGc = SystemClock.uptimeMillis();
20182             if (app.thread != null) {
20183                 if (app.reportLowMemory) {
20184                     app.reportLowMemory = false;
20185                     app.thread.scheduleLowMemory();
20186                 } else {
20187                     app.thread.processInBackground();
20188                 }
20189             }
20190         } catch (Exception e) {
20191             // whatever.
20192         }
20193     }
20194
20195     /**
20196      * Returns true if things are idle enough to perform GCs.
20197      */
20198     private final boolean canGcNowLocked() {
20199         boolean processingBroadcasts = false;
20200         for (BroadcastQueue q : mBroadcastQueues) {
20201             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20202                 processingBroadcasts = true;
20203             }
20204         }
20205         return !processingBroadcasts
20206                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20207     }
20208
20209     /**
20210      * Perform GCs on all processes that are waiting for it, but only
20211      * if things are idle.
20212      */
20213     final void performAppGcsLocked() {
20214         final int N = mProcessesToGc.size();
20215         if (N <= 0) {
20216             return;
20217         }
20218         if (canGcNowLocked()) {
20219             while (mProcessesToGc.size() > 0) {
20220                 ProcessRecord proc = mProcessesToGc.remove(0);
20221                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20222                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20223                             <= SystemClock.uptimeMillis()) {
20224                         // To avoid spamming the system, we will GC processes one
20225                         // at a time, waiting a few seconds between each.
20226                         performAppGcLocked(proc);
20227                         scheduleAppGcsLocked();
20228                         return;
20229                     } else {
20230                         // It hasn't been long enough since we last GCed this
20231                         // process...  put it in the list to wait for its time.
20232                         addProcessToGcListLocked(proc);
20233                         break;
20234                     }
20235                 }
20236             }
20237
20238             scheduleAppGcsLocked();
20239         }
20240     }
20241
20242     /**
20243      * If all looks good, perform GCs on all processes waiting for them.
20244      */
20245     final void performAppGcsIfAppropriateLocked() {
20246         if (canGcNowLocked()) {
20247             performAppGcsLocked();
20248             return;
20249         }
20250         // Still not idle, wait some more.
20251         scheduleAppGcsLocked();
20252     }
20253
20254     /**
20255      * Schedule the execution of all pending app GCs.
20256      */
20257     final void scheduleAppGcsLocked() {
20258         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20259
20260         if (mProcessesToGc.size() > 0) {
20261             // Schedule a GC for the time to the next process.
20262             ProcessRecord proc = mProcessesToGc.get(0);
20263             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20264
20265             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20266             long now = SystemClock.uptimeMillis();
20267             if (when < (now+GC_TIMEOUT)) {
20268                 when = now + GC_TIMEOUT;
20269             }
20270             mHandler.sendMessageAtTime(msg, when);
20271         }
20272     }
20273
20274     /**
20275      * Add a process to the array of processes waiting to be GCed.  Keeps the
20276      * list in sorted order by the last GC time.  The process can't already be
20277      * on the list.
20278      */
20279     final void addProcessToGcListLocked(ProcessRecord proc) {
20280         boolean added = false;
20281         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20282             if (mProcessesToGc.get(i).lastRequestedGc <
20283                     proc.lastRequestedGc) {
20284                 added = true;
20285                 mProcessesToGc.add(i+1, proc);
20286                 break;
20287             }
20288         }
20289         if (!added) {
20290             mProcessesToGc.add(0, proc);
20291         }
20292     }
20293
20294     /**
20295      * Set up to ask a process to GC itself.  This will either do it
20296      * immediately, or put it on the list of processes to gc the next
20297      * time things are idle.
20298      */
20299     final void scheduleAppGcLocked(ProcessRecord app) {
20300         long now = SystemClock.uptimeMillis();
20301         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20302             return;
20303         }
20304         if (!mProcessesToGc.contains(app)) {
20305             addProcessToGcListLocked(app);
20306             scheduleAppGcsLocked();
20307         }
20308     }
20309
20310     final void checkExcessivePowerUsageLocked(boolean doKills) {
20311         updateCpuStatsNow();
20312
20313         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20314         boolean doWakeKills = doKills;
20315         boolean doCpuKills = doKills;
20316         if (mLastPowerCheckRealtime == 0) {
20317             doWakeKills = false;
20318         }
20319         if (mLastPowerCheckUptime == 0) {
20320             doCpuKills = false;
20321         }
20322         if (stats.isScreenOn()) {
20323             doWakeKills = false;
20324         }
20325         final long curRealtime = SystemClock.elapsedRealtime();
20326         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20327         final long curUptime = SystemClock.uptimeMillis();
20328         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20329         mLastPowerCheckRealtime = curRealtime;
20330         mLastPowerCheckUptime = curUptime;
20331         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20332             doWakeKills = false;
20333         }
20334         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20335             doCpuKills = false;
20336         }
20337         int i = mLruProcesses.size();
20338         while (i > 0) {
20339             i--;
20340             ProcessRecord app = mLruProcesses.get(i);
20341             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20342                 long wtime;
20343                 synchronized (stats) {
20344                     wtime = stats.getProcessWakeTime(app.info.uid,
20345                             app.pid, curRealtime);
20346                 }
20347                 long wtimeUsed = wtime - app.lastWakeTime;
20348                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20349                 if (DEBUG_POWER) {
20350                     StringBuilder sb = new StringBuilder(128);
20351                     sb.append("Wake for ");
20352                     app.toShortString(sb);
20353                     sb.append(": over ");
20354                     TimeUtils.formatDuration(realtimeSince, sb);
20355                     sb.append(" used ");
20356                     TimeUtils.formatDuration(wtimeUsed, sb);
20357                     sb.append(" (");
20358                     sb.append((wtimeUsed*100)/realtimeSince);
20359                     sb.append("%)");
20360                     Slog.i(TAG_POWER, sb.toString());
20361                     sb.setLength(0);
20362                     sb.append("CPU for ");
20363                     app.toShortString(sb);
20364                     sb.append(": over ");
20365                     TimeUtils.formatDuration(uptimeSince, sb);
20366                     sb.append(" used ");
20367                     TimeUtils.formatDuration(cputimeUsed, sb);
20368                     sb.append(" (");
20369                     sb.append((cputimeUsed*100)/uptimeSince);
20370                     sb.append("%)");
20371                     Slog.i(TAG_POWER, sb.toString());
20372                 }
20373                 // If a process has held a wake lock for more
20374                 // than 50% of the time during this period,
20375                 // that sounds bad.  Kill!
20376                 if (doWakeKills && realtimeSince > 0
20377                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20378                     synchronized (stats) {
20379                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20380                                 realtimeSince, wtimeUsed);
20381                     }
20382                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20383                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20384                 } else if (doCpuKills && uptimeSince > 0
20385                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20386                     synchronized (stats) {
20387                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20388                                 uptimeSince, cputimeUsed);
20389                     }
20390                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20391                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20392                 } else {
20393                     app.lastWakeTime = wtime;
20394                     app.lastCpuTime = app.curCpuTime;
20395                 }
20396             }
20397         }
20398     }
20399
20400     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20401             long nowElapsed) {
20402         boolean success = true;
20403
20404         if (app.curRawAdj != app.setRawAdj) {
20405             app.setRawAdj = app.curRawAdj;
20406         }
20407
20408         int changes = 0;
20409
20410         if (app.curAdj != app.setAdj) {
20411             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20412             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20413                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20414                     + app.adjType);
20415             app.setAdj = app.curAdj;
20416             app.verifiedAdj = ProcessList.INVALID_ADJ;
20417         }
20418
20419         if (app.setSchedGroup != app.curSchedGroup) {
20420             int oldSchedGroup = app.setSchedGroup;
20421             app.setSchedGroup = app.curSchedGroup;
20422             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20423                     "Setting sched group of " + app.processName
20424                     + " to " + app.curSchedGroup);
20425             if (app.waitingToKill != null && app.curReceiver == null
20426                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20427                 app.kill(app.waitingToKill, true);
20428                 success = false;
20429             } else {
20430                 int processGroup;
20431                 switch (app.curSchedGroup) {
20432                     case ProcessList.SCHED_GROUP_BACKGROUND:
20433                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20434                         break;
20435                     case ProcessList.SCHED_GROUP_TOP_APP:
20436                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20437                         processGroup = Process.THREAD_GROUP_TOP_APP;
20438                         break;
20439                     default:
20440                         processGroup = Process.THREAD_GROUP_DEFAULT;
20441                         break;
20442                 }
20443                 long oldId = Binder.clearCallingIdentity();
20444                 try {
20445                     Process.setProcessGroup(app.pid, processGroup);
20446                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20447                         // do nothing if we already switched to RT
20448                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20449                             // Switch VR thread for app to SCHED_FIFO
20450                             if (mInVrMode && app.vrThreadTid != 0) {
20451                                 try {
20452                                     Process.setThreadScheduler(app.vrThreadTid,
20453                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20454                                 } catch (IllegalArgumentException e) {
20455                                     // thread died, ignore
20456                                 }
20457                             }
20458                             if (mUseFifoUiScheduling) {
20459                                 // Switch UI pipeline for app to SCHED_FIFO
20460                                 app.savedPriority = Process.getThreadPriority(app.pid);
20461                                 try {
20462                                     Process.setThreadScheduler(app.pid,
20463                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20464                                 } catch (IllegalArgumentException e) {
20465                                     // thread died, ignore
20466                                 }
20467                                 if (app.renderThreadTid != 0) {
20468                                     try {
20469                                         Process.setThreadScheduler(app.renderThreadTid,
20470                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20471                                     } catch (IllegalArgumentException e) {
20472                                         // thread died, ignore
20473                                     }
20474                                     if (DEBUG_OOM_ADJ) {
20475                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20476                                             app.renderThreadTid + ") to FIFO");
20477                                     }
20478                                 } else {
20479                                     if (DEBUG_OOM_ADJ) {
20480                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20481                                     }
20482                                 }
20483                             } else {
20484                                 // Boost priority for top app UI and render threads
20485                                 Process.setThreadPriority(app.pid, -10);
20486                                 if (app.renderThreadTid != 0) {
20487                                     try {
20488                                         Process.setThreadPriority(app.renderThreadTid, -10);
20489                                     } catch (IllegalArgumentException e) {
20490                                         // thread died, ignore
20491                                     }
20492                                 }
20493                             }
20494                         }
20495                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20496                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20497                         // Reset VR thread to SCHED_OTHER
20498                         // Safe to do even if we're not in VR mode
20499                         if (app.vrThreadTid != 0) {
20500                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20501                         }
20502                         if (mUseFifoUiScheduling) {
20503                             // Reset UI pipeline to SCHED_OTHER
20504                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20505                             Process.setThreadPriority(app.pid, app.savedPriority);
20506                             if (app.renderThreadTid != 0) {
20507                                 Process.setThreadScheduler(app.renderThreadTid,
20508                                     Process.SCHED_OTHER, 0);
20509                                 Process.setThreadPriority(app.renderThreadTid, -4);
20510                             }
20511                         } else {
20512                             // Reset priority for top app UI and render threads
20513                             Process.setThreadPriority(app.pid, 0);
20514                             if (app.renderThreadTid != 0) {
20515                                 Process.setThreadPriority(app.renderThreadTid, 0);
20516                             }
20517                         }
20518                     }
20519                 } catch (Exception e) {
20520                     Slog.w(TAG, "Failed setting process group of " + app.pid
20521                             + " to " + app.curSchedGroup);
20522                     e.printStackTrace();
20523                 } finally {
20524                     Binder.restoreCallingIdentity(oldId);
20525                 }
20526             }
20527         }
20528         if (app.repForegroundActivities != app.foregroundActivities) {
20529             app.repForegroundActivities = app.foregroundActivities;
20530             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20531         }
20532         if (app.repProcState != app.curProcState) {
20533             app.repProcState = app.curProcState;
20534             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20535             if (app.thread != null) {
20536                 try {
20537                     if (false) {
20538                         //RuntimeException h = new RuntimeException("here");
20539                         Slog.i(TAG, "Sending new process state " + app.repProcState
20540                                 + " to " + app /*, h*/);
20541                     }
20542                     app.thread.setProcessState(app.repProcState);
20543                 } catch (RemoteException e) {
20544                 }
20545             }
20546         }
20547         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20548                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20549             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20550                 // Experimental code to more aggressively collect pss while
20551                 // running test...  the problem is that this tends to collect
20552                 // the data right when a process is transitioning between process
20553                 // states, which well tend to give noisy data.
20554                 long start = SystemClock.uptimeMillis();
20555                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20556                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20557                 mPendingPssProcesses.remove(app);
20558                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20559                         + " to " + app.curProcState + ": "
20560                         + (SystemClock.uptimeMillis()-start) + "ms");
20561             }
20562             app.lastStateTime = now;
20563             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20564                     mTestPssMode, isSleepingLocked(), now);
20565             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20566                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20567                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20568                     + (app.nextPssTime-now) + ": " + app);
20569         } else {
20570             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20571                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20572                     mTestPssMode)))) {
20573                 requestPssLocked(app, app.setProcState);
20574                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20575                         mTestPssMode, isSleepingLocked(), now);
20576             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20577                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20578         }
20579         if (app.setProcState != app.curProcState) {
20580             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20581                     "Proc state change of " + app.processName
20582                             + " to " + app.curProcState);
20583             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20584             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20585             if (setImportant && !curImportant) {
20586                 // This app is no longer something we consider important enough to allow to
20587                 // use arbitrary amounts of battery power.  Note
20588                 // its current wake lock time to later know to kill it if
20589                 // it is not behaving well.
20590                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20591                 synchronized (stats) {
20592                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20593                             app.pid, nowElapsed);
20594                 }
20595                 app.lastCpuTime = app.curCpuTime;
20596
20597             }
20598             // Inform UsageStats of important process state change
20599             // Must be called before updating setProcState
20600             maybeUpdateUsageStatsLocked(app, nowElapsed);
20601
20602             app.setProcState = app.curProcState;
20603             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20604                 app.notCachedSinceIdle = false;
20605             }
20606             if (!doingAll) {
20607                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20608             } else {
20609                 app.procStateChanged = true;
20610             }
20611         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20612                 > USAGE_STATS_INTERACTION_INTERVAL) {
20613             // For apps that sit around for a long time in the interactive state, we need
20614             // to report this at least once a day so they don't go idle.
20615             maybeUpdateUsageStatsLocked(app, nowElapsed);
20616         }
20617
20618         if (changes != 0) {
20619             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20620                     "Changes in " + app + ": " + changes);
20621             int i = mPendingProcessChanges.size()-1;
20622             ProcessChangeItem item = null;
20623             while (i >= 0) {
20624                 item = mPendingProcessChanges.get(i);
20625                 if (item.pid == app.pid) {
20626                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20627                             "Re-using existing item: " + item);
20628                     break;
20629                 }
20630                 i--;
20631             }
20632             if (i < 0) {
20633                 // No existing item in pending changes; need a new one.
20634                 final int NA = mAvailProcessChanges.size();
20635                 if (NA > 0) {
20636                     item = mAvailProcessChanges.remove(NA-1);
20637                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20638                             "Retrieving available item: " + item);
20639                 } else {
20640                     item = new ProcessChangeItem();
20641                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20642                             "Allocating new item: " + item);
20643                 }
20644                 item.changes = 0;
20645                 item.pid = app.pid;
20646                 item.uid = app.info.uid;
20647                 if (mPendingProcessChanges.size() == 0) {
20648                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20649                             "*** Enqueueing dispatch processes changed!");
20650                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20651                 }
20652                 mPendingProcessChanges.add(item);
20653             }
20654             item.changes |= changes;
20655             item.processState = app.repProcState;
20656             item.foregroundActivities = app.repForegroundActivities;
20657             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20658                     "Item " + Integer.toHexString(System.identityHashCode(item))
20659                     + " " + app.toShortString() + ": changes=" + item.changes
20660                     + " procState=" + item.processState
20661                     + " foreground=" + item.foregroundActivities
20662                     + " type=" + app.adjType + " source=" + app.adjSource
20663                     + " target=" + app.adjTarget);
20664         }
20665
20666         return success;
20667     }
20668
20669     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20670         final UidRecord.ChangeItem pendingChange;
20671         if (uidRec == null || uidRec.pendingChange == null) {
20672             if (mPendingUidChanges.size() == 0) {
20673                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20674                         "*** Enqueueing dispatch uid changed!");
20675                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20676             }
20677             final int NA = mAvailUidChanges.size();
20678             if (NA > 0) {
20679                 pendingChange = mAvailUidChanges.remove(NA-1);
20680                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20681                         "Retrieving available item: " + pendingChange);
20682             } else {
20683                 pendingChange = new UidRecord.ChangeItem();
20684                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20685                         "Allocating new item: " + pendingChange);
20686             }
20687             if (uidRec != null) {
20688                 uidRec.pendingChange = pendingChange;
20689                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20690                     // If this uid is going away, and we haven't yet reported it is gone,
20691                     // then do so now.
20692                     change = UidRecord.CHANGE_GONE_IDLE;
20693                 }
20694             } else if (uid < 0) {
20695                 throw new IllegalArgumentException("No UidRecord or uid");
20696             }
20697             pendingChange.uidRecord = uidRec;
20698             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20699             mPendingUidChanges.add(pendingChange);
20700         } else {
20701             pendingChange = uidRec.pendingChange;
20702             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20703                 change = UidRecord.CHANGE_GONE_IDLE;
20704             }
20705         }
20706         pendingChange.change = change;
20707         pendingChange.processState = uidRec != null
20708                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20709     }
20710
20711     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20712             String authority) {
20713         if (app == null) return;
20714         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20715             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20716             if (userState == null) return;
20717             final long now = SystemClock.elapsedRealtime();
20718             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20719             if (lastReported == null || lastReported < now - 60 * 1000L) {
20720                 mUsageStatsService.reportContentProviderUsage(
20721                         authority, providerPkgName, app.userId);
20722                 userState.mProviderLastReportedFg.put(authority, now);
20723             }
20724         }
20725     }
20726
20727     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20728         if (DEBUG_USAGE_STATS) {
20729             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20730                     + "] state changes: old = " + app.setProcState + ", new = "
20731                     + app.curProcState);
20732         }
20733         if (mUsageStatsService == null) {
20734             return;
20735         }
20736         boolean isInteraction;
20737         // To avoid some abuse patterns, we are going to be careful about what we consider
20738         // to be an app interaction.  Being the top activity doesn't count while the display
20739         // is sleeping, nor do short foreground services.
20740         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20741             isInteraction = true;
20742             app.fgInteractionTime = 0;
20743         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20744             if (app.fgInteractionTime == 0) {
20745                 app.fgInteractionTime = nowElapsed;
20746                 isInteraction = false;
20747             } else {
20748                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20749             }
20750         } else {
20751             isInteraction = app.curProcState
20752                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20753             app.fgInteractionTime = 0;
20754         }
20755         if (isInteraction && (!app.reportedInteraction
20756                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20757             app.interactionEventTime = nowElapsed;
20758             String[] packages = app.getPackageList();
20759             if (packages != null) {
20760                 for (int i = 0; i < packages.length; i++) {
20761                     mUsageStatsService.reportEvent(packages[i], app.userId,
20762                             UsageEvents.Event.SYSTEM_INTERACTION);
20763                 }
20764             }
20765         }
20766         app.reportedInteraction = isInteraction;
20767         if (!isInteraction) {
20768             app.interactionEventTime = 0;
20769         }
20770     }
20771
20772     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20773         if (proc.thread != null) {
20774             if (proc.baseProcessTracker != null) {
20775                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20776             }
20777         }
20778     }
20779
20780     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20781             ProcessRecord TOP_APP, boolean doingAll, long now) {
20782         if (app.thread == null) {
20783             return false;
20784         }
20785
20786         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20787
20788         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20789     }
20790
20791     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20792             boolean oomAdj) {
20793         if (isForeground != proc.foregroundServices) {
20794             proc.foregroundServices = isForeground;
20795             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20796                     proc.info.uid);
20797             if (isForeground) {
20798                 if (curProcs == null) {
20799                     curProcs = new ArrayList<ProcessRecord>();
20800                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20801                 }
20802                 if (!curProcs.contains(proc)) {
20803                     curProcs.add(proc);
20804                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20805                             proc.info.packageName, proc.info.uid);
20806                 }
20807             } else {
20808                 if (curProcs != null) {
20809                     if (curProcs.remove(proc)) {
20810                         mBatteryStatsService.noteEvent(
20811                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20812                                 proc.info.packageName, proc.info.uid);
20813                         if (curProcs.size() <= 0) {
20814                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20815                         }
20816                     }
20817                 }
20818             }
20819             if (oomAdj) {
20820                 updateOomAdjLocked();
20821             }
20822         }
20823     }
20824
20825     private final ActivityRecord resumedAppLocked() {
20826         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20827         String pkg;
20828         int uid;
20829         if (act != null) {
20830             pkg = act.packageName;
20831             uid = act.info.applicationInfo.uid;
20832         } else {
20833             pkg = null;
20834             uid = -1;
20835         }
20836         // Has the UID or resumed package name changed?
20837         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20838                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20839             if (mCurResumedPackage != null) {
20840                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20841                         mCurResumedPackage, mCurResumedUid);
20842             }
20843             mCurResumedPackage = pkg;
20844             mCurResumedUid = uid;
20845             if (mCurResumedPackage != null) {
20846                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20847                         mCurResumedPackage, mCurResumedUid);
20848             }
20849         }
20850         return act;
20851     }
20852
20853     final boolean updateOomAdjLocked(ProcessRecord app) {
20854         final ActivityRecord TOP_ACT = resumedAppLocked();
20855         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20856         final boolean wasCached = app.cached;
20857
20858         mAdjSeq++;
20859
20860         // This is the desired cached adjusment we want to tell it to use.
20861         // If our app is currently cached, we know it, and that is it.  Otherwise,
20862         // we don't know it yet, and it needs to now be cached we will then
20863         // need to do a complete oom adj.
20864         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20865                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20866         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20867                 SystemClock.uptimeMillis());
20868         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20869             // Changed to/from cached state, so apps after it in the LRU
20870             // list may also be changed.
20871             updateOomAdjLocked();
20872         }
20873         return success;
20874     }
20875
20876     final void updateOomAdjLocked() {
20877         final ActivityRecord TOP_ACT = resumedAppLocked();
20878         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20879         final long now = SystemClock.uptimeMillis();
20880         final long nowElapsed = SystemClock.elapsedRealtime();
20881         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20882         final int N = mLruProcesses.size();
20883
20884         if (false) {
20885             RuntimeException e = new RuntimeException();
20886             e.fillInStackTrace();
20887             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20888         }
20889
20890         // Reset state in all uid records.
20891         for (int i=mActiveUids.size()-1; i>=0; i--) {
20892             final UidRecord uidRec = mActiveUids.valueAt(i);
20893             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20894                     "Starting update of " + uidRec);
20895             uidRec.reset();
20896         }
20897
20898         mStackSupervisor.rankTaskLayersIfNeeded();
20899
20900         mAdjSeq++;
20901         mNewNumServiceProcs = 0;
20902         mNewNumAServiceProcs = 0;
20903
20904         final int emptyProcessLimit;
20905         final int cachedProcessLimit;
20906         if (mProcessLimit <= 0) {
20907             emptyProcessLimit = cachedProcessLimit = 0;
20908         } else if (mProcessLimit == 1) {
20909             emptyProcessLimit = 1;
20910             cachedProcessLimit = 0;
20911         } else {
20912             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20913             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20914         }
20915
20916         // Let's determine how many processes we have running vs.
20917         // how many slots we have for background processes; we may want
20918         // to put multiple processes in a slot of there are enough of
20919         // them.
20920         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20921                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20922         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20923         if (numEmptyProcs > cachedProcessLimit) {
20924             // If there are more empty processes than our limit on cached
20925             // processes, then use the cached process limit for the factor.
20926             // This ensures that the really old empty processes get pushed
20927             // down to the bottom, so if we are running low on memory we will
20928             // have a better chance at keeping around more cached processes
20929             // instead of a gazillion empty processes.
20930             numEmptyProcs = cachedProcessLimit;
20931         }
20932         int emptyFactor = numEmptyProcs/numSlots;
20933         if (emptyFactor < 1) emptyFactor = 1;
20934         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20935         if (cachedFactor < 1) cachedFactor = 1;
20936         int stepCached = 0;
20937         int stepEmpty = 0;
20938         int numCached = 0;
20939         int numEmpty = 0;
20940         int numTrimming = 0;
20941
20942         mNumNonCachedProcs = 0;
20943         mNumCachedHiddenProcs = 0;
20944
20945         // First update the OOM adjustment for each of the
20946         // application processes based on their current state.
20947         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20948         int nextCachedAdj = curCachedAdj+1;
20949         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20950         int nextEmptyAdj = curEmptyAdj+2;
20951         for (int i=N-1; i>=0; i--) {
20952             ProcessRecord app = mLruProcesses.get(i);
20953             if (!app.killedByAm && app.thread != null) {
20954                 app.procStateChanged = false;
20955                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20956
20957                 // If we haven't yet assigned the final cached adj
20958                 // to the process, do that now.
20959                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20960                     switch (app.curProcState) {
20961                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20962                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20963                             // This process is a cached process holding activities...
20964                             // assign it the next cached value for that type, and then
20965                             // step that cached level.
20966                             app.curRawAdj = curCachedAdj;
20967                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20968                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20969                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20970                                     + ")");
20971                             if (curCachedAdj != nextCachedAdj) {
20972                                 stepCached++;
20973                                 if (stepCached >= cachedFactor) {
20974                                     stepCached = 0;
20975                                     curCachedAdj = nextCachedAdj;
20976                                     nextCachedAdj += 2;
20977                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20978                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20979                                     }
20980                                 }
20981                             }
20982                             break;
20983                         default:
20984                             // For everything else, assign next empty cached process
20985                             // level and bump that up.  Note that this means that
20986                             // long-running services that have dropped down to the
20987                             // cached level will be treated as empty (since their process
20988                             // state is still as a service), which is what we want.
20989                             app.curRawAdj = curEmptyAdj;
20990                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20991                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20992                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20993                                     + ")");
20994                             if (curEmptyAdj != nextEmptyAdj) {
20995                                 stepEmpty++;
20996                                 if (stepEmpty >= emptyFactor) {
20997                                     stepEmpty = 0;
20998                                     curEmptyAdj = nextEmptyAdj;
20999                                     nextEmptyAdj += 2;
21000                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21001                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21002                                     }
21003                                 }
21004                             }
21005                             break;
21006                     }
21007                 }
21008
21009                 applyOomAdjLocked(app, true, now, nowElapsed);
21010
21011                 // Count the number of process types.
21012                 switch (app.curProcState) {
21013                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21014                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21015                         mNumCachedHiddenProcs++;
21016                         numCached++;
21017                         if (numCached > cachedProcessLimit) {
21018                             app.kill("cached #" + numCached, true);
21019                         }
21020                         break;
21021                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21022                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21023                                 && app.lastActivityTime < oldTime) {
21024                             app.kill("empty for "
21025                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21026                                     / 1000) + "s", true);
21027                         } else {
21028                             numEmpty++;
21029                             if (numEmpty > emptyProcessLimit) {
21030                                 app.kill("empty #" + numEmpty, true);
21031                             }
21032                         }
21033                         break;
21034                     default:
21035                         mNumNonCachedProcs++;
21036                         break;
21037                 }
21038
21039                 if (app.isolated && app.services.size() <= 0) {
21040                     // If this is an isolated process, and there are no
21041                     // services running in it, then the process is no longer
21042                     // needed.  We agressively kill these because we can by
21043                     // definition not re-use the same process again, and it is
21044                     // good to avoid having whatever code was running in them
21045                     // left sitting around after no longer needed.
21046                     app.kill("isolated not needed", true);
21047                 } else {
21048                     // Keeping this process, update its uid.
21049                     final UidRecord uidRec = app.uidRecord;
21050                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
21051                         uidRec.curProcState = app.curProcState;
21052                     }
21053                 }
21054
21055                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21056                         && !app.killedByAm) {
21057                     numTrimming++;
21058                 }
21059             }
21060         }
21061
21062         mNumServiceProcs = mNewNumServiceProcs;
21063
21064         // Now determine the memory trimming level of background processes.
21065         // Unfortunately we need to start at the back of the list to do this
21066         // properly.  We only do this if the number of background apps we
21067         // are managing to keep around is less than half the maximum we desire;
21068         // if we are keeping a good number around, we'll let them use whatever
21069         // memory they want.
21070         final int numCachedAndEmpty = numCached + numEmpty;
21071         int memFactor;
21072         if (numCached <= ProcessList.TRIM_CACHED_APPS
21073                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21074             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21075                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21076             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21077                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21078             } else {
21079                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21080             }
21081         } else {
21082             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21083         }
21084         // We always allow the memory level to go up (better).  We only allow it to go
21085         // down if we are in a state where that is allowed, *and* the total number of processes
21086         // has gone down since last time.
21087         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21088                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21089                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21090         if (memFactor > mLastMemoryLevel) {
21091             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21092                 memFactor = mLastMemoryLevel;
21093                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21094             }
21095         }
21096         if (memFactor != mLastMemoryLevel) {
21097             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21098         }
21099         mLastMemoryLevel = memFactor;
21100         mLastNumProcesses = mLruProcesses.size();
21101         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21102         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21103         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21104             if (mLowRamStartTime == 0) {
21105                 mLowRamStartTime = now;
21106             }
21107             int step = 0;
21108             int fgTrimLevel;
21109             switch (memFactor) {
21110                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21111                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21112                     break;
21113                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21114                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21115                     break;
21116                 default:
21117                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21118                     break;
21119             }
21120             int factor = numTrimming/3;
21121             int minFactor = 2;
21122             if (mHomeProcess != null) minFactor++;
21123             if (mPreviousProcess != null) minFactor++;
21124             if (factor < minFactor) factor = minFactor;
21125             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21126             for (int i=N-1; i>=0; i--) {
21127                 ProcessRecord app = mLruProcesses.get(i);
21128                 if (allChanged || app.procStateChanged) {
21129                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21130                     app.procStateChanged = false;
21131                 }
21132                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21133                         && !app.killedByAm) {
21134                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21135                         try {
21136                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21137                                     "Trimming memory of " + app.processName + " to " + curLevel);
21138                             app.thread.scheduleTrimMemory(curLevel);
21139                         } catch (RemoteException e) {
21140                         }
21141                         if (false) {
21142                             // For now we won't do this; our memory trimming seems
21143                             // to be good enough at this point that destroying
21144                             // activities causes more harm than good.
21145                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21146                                     && app != mHomeProcess && app != mPreviousProcess) {
21147                                 // Need to do this on its own message because the stack may not
21148                                 // be in a consistent state at this point.
21149                                 // For these apps we will also finish their activities
21150                                 // to help them free memory.
21151                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21152                             }
21153                         }
21154                     }
21155                     app.trimMemoryLevel = curLevel;
21156                     step++;
21157                     if (step >= factor) {
21158                         step = 0;
21159                         switch (curLevel) {
21160                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21161                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21162                                 break;
21163                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21164                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21165                                 break;
21166                         }
21167                     }
21168                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21169                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21170                             && app.thread != null) {
21171                         try {
21172                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21173                                     "Trimming memory of heavy-weight " + app.processName
21174                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21175                             app.thread.scheduleTrimMemory(
21176                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21177                         } catch (RemoteException e) {
21178                         }
21179                     }
21180                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21181                 } else {
21182                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21183                             || app.systemNoUi) && app.pendingUiClean) {
21184                         // If this application is now in the background and it
21185                         // had done UI, then give it the special trim level to
21186                         // have it free UI resources.
21187                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21188                         if (app.trimMemoryLevel < level && app.thread != null) {
21189                             try {
21190                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21191                                         "Trimming memory of bg-ui " + app.processName
21192                                         + " to " + level);
21193                                 app.thread.scheduleTrimMemory(level);
21194                             } catch (RemoteException e) {
21195                             }
21196                         }
21197                         app.pendingUiClean = false;
21198                     }
21199                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21200                         try {
21201                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21202                                     "Trimming memory of fg " + app.processName
21203                                     + " to " + fgTrimLevel);
21204                             app.thread.scheduleTrimMemory(fgTrimLevel);
21205                         } catch (RemoteException e) {
21206                         }
21207                     }
21208                     app.trimMemoryLevel = fgTrimLevel;
21209                 }
21210             }
21211         } else {
21212             if (mLowRamStartTime != 0) {
21213                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21214                 mLowRamStartTime = 0;
21215             }
21216             for (int i=N-1; i>=0; i--) {
21217                 ProcessRecord app = mLruProcesses.get(i);
21218                 if (allChanged || app.procStateChanged) {
21219                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21220                     app.procStateChanged = false;
21221                 }
21222                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21223                         || app.systemNoUi) && app.pendingUiClean) {
21224                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21225                             && app.thread != null) {
21226                         try {
21227                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21228                                     "Trimming memory of ui hidden " + app.processName
21229                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21230                             app.thread.scheduleTrimMemory(
21231                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21232                         } catch (RemoteException e) {
21233                         }
21234                     }
21235                     app.pendingUiClean = false;
21236                 }
21237                 app.trimMemoryLevel = 0;
21238             }
21239         }
21240
21241         if (mAlwaysFinishActivities) {
21242             // Need to do this on its own message because the stack may not
21243             // be in a consistent state at this point.
21244             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21245         }
21246
21247         if (allChanged) {
21248             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21249         }
21250
21251         // Update from any uid changes.
21252         for (int i=mActiveUids.size()-1; i>=0; i--) {
21253             final UidRecord uidRec = mActiveUids.valueAt(i);
21254             int uidChange = UidRecord.CHANGE_PROCSTATE;
21255             if (uidRec.setProcState != uidRec.curProcState) {
21256                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21257                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21258                         + " to " + uidRec.curProcState);
21259                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21260                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21261                         uidRec.lastBackgroundTime = nowElapsed;
21262                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21263                             // Note: the background settle time is in elapsed realtime, while
21264                             // the handler time base is uptime.  All this means is that we may
21265                             // stop background uids later than we had intended, but that only
21266                             // happens because the device was sleeping so we are okay anyway.
21267                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21268                         }
21269                     }
21270                 } else {
21271                     if (uidRec.idle) {
21272                         uidChange = UidRecord.CHANGE_ACTIVE;
21273                         uidRec.idle = false;
21274                     }
21275                     uidRec.lastBackgroundTime = 0;
21276                 }
21277                 uidRec.setProcState = uidRec.curProcState;
21278                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21279                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21280             }
21281         }
21282
21283         if (mProcessStats.shouldWriteNowLocked(now)) {
21284             mHandler.post(new Runnable() {
21285                 @Override public void run() {
21286                     synchronized (ActivityManagerService.this) {
21287                         mProcessStats.writeStateAsyncLocked();
21288                     }
21289                 }
21290             });
21291         }
21292
21293         if (DEBUG_OOM_ADJ) {
21294             final long duration = SystemClock.uptimeMillis() - now;
21295             if (false) {
21296                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21297                         new RuntimeException("here").fillInStackTrace());
21298             } else {
21299                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21300             }
21301         }
21302     }
21303
21304     final void idleUids() {
21305         synchronized (this) {
21306             final long nowElapsed = SystemClock.elapsedRealtime();
21307             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21308             long nextTime = 0;
21309             for (int i=mActiveUids.size()-1; i>=0; i--) {
21310                 final UidRecord uidRec = mActiveUids.valueAt(i);
21311                 final long bgTime = uidRec.lastBackgroundTime;
21312                 if (bgTime > 0 && !uidRec.idle) {
21313                     if (bgTime <= maxBgTime) {
21314                         uidRec.idle = true;
21315                         doStopUidLocked(uidRec.uid, uidRec);
21316                     } else {
21317                         if (nextTime == 0 || nextTime > bgTime) {
21318                             nextTime = bgTime;
21319                         }
21320                     }
21321                 }
21322             }
21323             if (nextTime > 0) {
21324                 mHandler.removeMessages(IDLE_UIDS_MSG);
21325                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21326                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21327             }
21328         }
21329     }
21330
21331     final void runInBackgroundDisabled(int uid) {
21332         synchronized (this) {
21333             UidRecord uidRec = mActiveUids.get(uid);
21334             if (uidRec != null) {
21335                 // This uid is actually running...  should it be considered background now?
21336                 if (uidRec.idle) {
21337                     doStopUidLocked(uidRec.uid, uidRec);
21338                 }
21339             } else {
21340                 // This uid isn't actually running...  still send a report about it being "stopped".
21341                 doStopUidLocked(uid, null);
21342             }
21343         }
21344     }
21345
21346     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21347         mServices.stopInBackgroundLocked(uid);
21348         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21349     }
21350
21351     final void trimApplications() {
21352         synchronized (this) {
21353             int i;
21354
21355             // First remove any unused application processes whose package
21356             // has been removed.
21357             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21358                 final ProcessRecord app = mRemovedProcesses.get(i);
21359                 if (app.activities.size() == 0
21360                         && app.curReceiver == null && app.services.size() == 0) {
21361                     Slog.i(
21362                         TAG, "Exiting empty application process "
21363                         + app.toShortString() + " ("
21364                         + (app.thread != null ? app.thread.asBinder() : null)
21365                         + ")\n");
21366                     if (app.pid > 0 && app.pid != MY_PID) {
21367                         app.kill("empty", false);
21368                     } else {
21369                         try {
21370                             app.thread.scheduleExit();
21371                         } catch (Exception e) {
21372                             // Ignore exceptions.
21373                         }
21374                     }
21375                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21376                     mRemovedProcesses.remove(i);
21377
21378                     if (app.persistent) {
21379                         addAppLocked(app.info, false, null /* ABI override */);
21380                     }
21381                 }
21382             }
21383
21384             // Now update the oom adj for all processes.
21385             updateOomAdjLocked();
21386         }
21387     }
21388
21389     /** This method sends the specified signal to each of the persistent apps */
21390     public void signalPersistentProcesses(int sig) throws RemoteException {
21391         if (sig != Process.SIGNAL_USR1) {
21392             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21393         }
21394
21395         synchronized (this) {
21396             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21397                     != PackageManager.PERMISSION_GRANTED) {
21398                 throw new SecurityException("Requires permission "
21399                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21400             }
21401
21402             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21403                 ProcessRecord r = mLruProcesses.get(i);
21404                 if (r.thread != null && r.persistent) {
21405                     Process.sendSignal(r.pid, sig);
21406                 }
21407             }
21408         }
21409     }
21410
21411     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21412         if (proc == null || proc == mProfileProc) {
21413             proc = mProfileProc;
21414             profileType = mProfileType;
21415             clearProfilerLocked();
21416         }
21417         if (proc == null) {
21418             return;
21419         }
21420         try {
21421             proc.thread.profilerControl(false, null, profileType);
21422         } catch (RemoteException e) {
21423             throw new IllegalStateException("Process disappeared");
21424         }
21425     }
21426
21427     private void clearProfilerLocked() {
21428         if (mProfileFd != null) {
21429             try {
21430                 mProfileFd.close();
21431             } catch (IOException e) {
21432             }
21433         }
21434         mProfileApp = null;
21435         mProfileProc = null;
21436         mProfileFile = null;
21437         mProfileType = 0;
21438         mAutoStopProfiler = false;
21439         mSamplingInterval = 0;
21440     }
21441
21442     public boolean profileControl(String process, int userId, boolean start,
21443             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21444
21445         try {
21446             synchronized (this) {
21447                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21448                 // its own permission.
21449                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21450                         != PackageManager.PERMISSION_GRANTED) {
21451                     throw new SecurityException("Requires permission "
21452                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21453                 }
21454
21455                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21456                     throw new IllegalArgumentException("null profile info or fd");
21457                 }
21458
21459                 ProcessRecord proc = null;
21460                 if (process != null) {
21461                     proc = findProcessLocked(process, userId, "profileControl");
21462                 }
21463
21464                 if (start && (proc == null || proc.thread == null)) {
21465                     throw new IllegalArgumentException("Unknown process: " + process);
21466                 }
21467
21468                 if (start) {
21469                     stopProfilerLocked(null, 0);
21470                     setProfileApp(proc.info, proc.processName, profilerInfo);
21471                     mProfileProc = proc;
21472                     mProfileType = profileType;
21473                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21474                     try {
21475                         fd = fd.dup();
21476                     } catch (IOException e) {
21477                         fd = null;
21478                     }
21479                     profilerInfo.profileFd = fd;
21480                     proc.thread.profilerControl(start, profilerInfo, profileType);
21481                     fd = null;
21482                     mProfileFd = null;
21483                 } else {
21484                     stopProfilerLocked(proc, profileType);
21485                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21486                         try {
21487                             profilerInfo.profileFd.close();
21488                         } catch (IOException e) {
21489                         }
21490                     }
21491                 }
21492
21493                 return true;
21494             }
21495         } catch (RemoteException e) {
21496             throw new IllegalStateException("Process disappeared");
21497         } finally {
21498             if (profilerInfo != null && profilerInfo.profileFd != null) {
21499                 try {
21500                     profilerInfo.profileFd.close();
21501                 } catch (IOException e) {
21502                 }
21503             }
21504         }
21505     }
21506
21507     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21508         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21509                 userId, true, ALLOW_FULL_ONLY, callName, null);
21510         ProcessRecord proc = null;
21511         try {
21512             int pid = Integer.parseInt(process);
21513             synchronized (mPidsSelfLocked) {
21514                 proc = mPidsSelfLocked.get(pid);
21515             }
21516         } catch (NumberFormatException e) {
21517         }
21518
21519         if (proc == null) {
21520             ArrayMap<String, SparseArray<ProcessRecord>> all
21521                     = mProcessNames.getMap();
21522             SparseArray<ProcessRecord> procs = all.get(process);
21523             if (procs != null && procs.size() > 0) {
21524                 proc = procs.valueAt(0);
21525                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21526                     for (int i=1; i<procs.size(); i++) {
21527                         ProcessRecord thisProc = procs.valueAt(i);
21528                         if (thisProc.userId == userId) {
21529                             proc = thisProc;
21530                             break;
21531                         }
21532                     }
21533                 }
21534             }
21535         }
21536
21537         return proc;
21538     }
21539
21540     public boolean dumpHeap(String process, int userId, boolean managed,
21541             String path, ParcelFileDescriptor fd) throws RemoteException {
21542
21543         try {
21544             synchronized (this) {
21545                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21546                 // its own permission (same as profileControl).
21547                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21548                         != PackageManager.PERMISSION_GRANTED) {
21549                     throw new SecurityException("Requires permission "
21550                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21551                 }
21552
21553                 if (fd == null) {
21554                     throw new IllegalArgumentException("null fd");
21555                 }
21556
21557                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21558                 if (proc == null || proc.thread == null) {
21559                     throw new IllegalArgumentException("Unknown process: " + process);
21560                 }
21561
21562                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21563                 if (!isDebuggable) {
21564                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21565                         throw new SecurityException("Process not debuggable: " + proc);
21566                     }
21567                 }
21568
21569                 proc.thread.dumpHeap(managed, path, fd);
21570                 fd = null;
21571                 return true;
21572             }
21573         } catch (RemoteException e) {
21574             throw new IllegalStateException("Process disappeared");
21575         } finally {
21576             if (fd != null) {
21577                 try {
21578                     fd.close();
21579                 } catch (IOException e) {
21580                 }
21581             }
21582         }
21583     }
21584
21585     @Override
21586     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21587             String reportPackage) {
21588         if (processName != null) {
21589             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21590                     "setDumpHeapDebugLimit()");
21591         } else {
21592             synchronized (mPidsSelfLocked) {
21593                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21594                 if (proc == null) {
21595                     throw new SecurityException("No process found for calling pid "
21596                             + Binder.getCallingPid());
21597                 }
21598                 if (!Build.IS_DEBUGGABLE
21599                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21600                     throw new SecurityException("Not running a debuggable build");
21601                 }
21602                 processName = proc.processName;
21603                 uid = proc.uid;
21604                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21605                     throw new SecurityException("Package " + reportPackage + " is not running in "
21606                             + proc);
21607                 }
21608             }
21609         }
21610         synchronized (this) {
21611             if (maxMemSize > 0) {
21612                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21613             } else {
21614                 if (uid != 0) {
21615                     mMemWatchProcesses.remove(processName, uid);
21616                 } else {
21617                     mMemWatchProcesses.getMap().remove(processName);
21618                 }
21619             }
21620         }
21621     }
21622
21623     @Override
21624     public void dumpHeapFinished(String path) {
21625         synchronized (this) {
21626             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21627                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21628                         + " does not match last pid " + mMemWatchDumpPid);
21629                 return;
21630             }
21631             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21632                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21633                         + " does not match last path " + mMemWatchDumpFile);
21634                 return;
21635             }
21636             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21637             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21638         }
21639     }
21640
21641     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21642     public void monitor() {
21643         synchronized (this) { }
21644     }
21645
21646     void onCoreSettingsChange(Bundle settings) {
21647         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21648             ProcessRecord processRecord = mLruProcesses.get(i);
21649             try {
21650                 if (processRecord.thread != null) {
21651                     processRecord.thread.setCoreSettings(settings);
21652                 }
21653             } catch (RemoteException re) {
21654                 /* ignore */
21655             }
21656         }
21657     }
21658
21659     // Multi-user methods
21660
21661     /**
21662      * Start user, if its not already running, but don't bring it to foreground.
21663      */
21664     @Override
21665     public boolean startUserInBackground(final int userId) {
21666         return mUserController.startUser(userId, /* foreground */ false);
21667     }
21668
21669     @Override
21670     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21671         return mUserController.unlockUser(userId, token, secret, listener);
21672     }
21673
21674     @Override
21675     public boolean switchUser(final int targetUserId) {
21676         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21677         UserInfo currentUserInfo;
21678         UserInfo targetUserInfo;
21679         synchronized (this) {
21680             int currentUserId = mUserController.getCurrentUserIdLocked();
21681             currentUserInfo = mUserController.getUserInfo(currentUserId);
21682             targetUserInfo = mUserController.getUserInfo(targetUserId);
21683             if (targetUserInfo == null) {
21684                 Slog.w(TAG, "No user info for user #" + targetUserId);
21685                 return false;
21686             }
21687             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21688                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21689                         + " when device is in demo mode");
21690                 return false;
21691             }
21692             if (!targetUserInfo.supportsSwitchTo()) {
21693                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21694                 return false;
21695             }
21696             if (targetUserInfo.isManagedProfile()) {
21697                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21698                 return false;
21699             }
21700             mUserController.setTargetUserIdLocked(targetUserId);
21701         }
21702         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21703         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21704         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21705         return true;
21706     }
21707
21708     void scheduleStartProfilesLocked() {
21709         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21710             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21711                     DateUtils.SECOND_IN_MILLIS);
21712         }
21713     }
21714
21715     @Override
21716     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21717         return mUserController.stopUser(userId, force, callback);
21718     }
21719
21720     @Override
21721     public UserInfo getCurrentUser() {
21722         return mUserController.getCurrentUser();
21723     }
21724
21725     @Override
21726     public boolean isUserRunning(int userId, int flags) {
21727         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21728                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21729                     != PackageManager.PERMISSION_GRANTED) {
21730             String msg = "Permission Denial: isUserRunning() from pid="
21731                     + Binder.getCallingPid()
21732                     + ", uid=" + Binder.getCallingUid()
21733                     + " requires " + INTERACT_ACROSS_USERS;
21734             Slog.w(TAG, msg);
21735             throw new SecurityException(msg);
21736         }
21737         synchronized (this) {
21738             return mUserController.isUserRunningLocked(userId, flags);
21739         }
21740     }
21741
21742     @Override
21743     public int[] getRunningUserIds() {
21744         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21745                 != PackageManager.PERMISSION_GRANTED) {
21746             String msg = "Permission Denial: isUserRunning() from pid="
21747                     + Binder.getCallingPid()
21748                     + ", uid=" + Binder.getCallingUid()
21749                     + " requires " + INTERACT_ACROSS_USERS;
21750             Slog.w(TAG, msg);
21751             throw new SecurityException(msg);
21752         }
21753         synchronized (this) {
21754             return mUserController.getStartedUserArrayLocked();
21755         }
21756     }
21757
21758     @Override
21759     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21760         mUserController.registerUserSwitchObserver(observer, name);
21761     }
21762
21763     @Override
21764     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21765         mUserController.unregisterUserSwitchObserver(observer);
21766     }
21767
21768     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21769         if (info == null) return null;
21770         ApplicationInfo newInfo = new ApplicationInfo(info);
21771         newInfo.initForUser(userId);
21772         return newInfo;
21773     }
21774
21775     public boolean isUserStopped(int userId) {
21776         synchronized (this) {
21777             return mUserController.getStartedUserStateLocked(userId) == null;
21778         }
21779     }
21780
21781     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21782         if (aInfo == null
21783                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21784             return aInfo;
21785         }
21786
21787         ActivityInfo info = new ActivityInfo(aInfo);
21788         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21789         return info;
21790     }
21791
21792     private boolean processSanityChecksLocked(ProcessRecord process) {
21793         if (process == null || process.thread == null) {
21794             return false;
21795         }
21796
21797         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21798         if (!isDebuggable) {
21799             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21800                 return false;
21801             }
21802         }
21803
21804         return true;
21805     }
21806
21807     public boolean startBinderTracking() throws RemoteException {
21808         synchronized (this) {
21809             mBinderTransactionTrackingEnabled = true;
21810             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21811             // permission (same as profileControl).
21812             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21813                     != PackageManager.PERMISSION_GRANTED) {
21814                 throw new SecurityException("Requires permission "
21815                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21816             }
21817
21818             for (int i = 0; i < mLruProcesses.size(); i++) {
21819                 ProcessRecord process = mLruProcesses.get(i);
21820                 if (!processSanityChecksLocked(process)) {
21821                     continue;
21822                 }
21823                 try {
21824                     process.thread.startBinderTracking();
21825                 } catch (RemoteException e) {
21826                     Log.v(TAG, "Process disappared");
21827                 }
21828             }
21829             return true;
21830         }
21831     }
21832
21833     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21834         try {
21835             synchronized (this) {
21836                 mBinderTransactionTrackingEnabled = false;
21837                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21838                 // permission (same as profileControl).
21839                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21840                         != PackageManager.PERMISSION_GRANTED) {
21841                     throw new SecurityException("Requires permission "
21842                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21843                 }
21844
21845                 if (fd == null) {
21846                     throw new IllegalArgumentException("null fd");
21847                 }
21848
21849                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21850                 pw.println("Binder transaction traces for all processes.\n");
21851                 for (ProcessRecord process : mLruProcesses) {
21852                     if (!processSanityChecksLocked(process)) {
21853                         continue;
21854                     }
21855
21856                     pw.println("Traces for process: " + process.processName);
21857                     pw.flush();
21858                     try {
21859                         TransferPipe tp = new TransferPipe();
21860                         try {
21861                             process.thread.stopBinderTrackingAndDump(
21862                                     tp.getWriteFd().getFileDescriptor());
21863                             tp.go(fd.getFileDescriptor());
21864                         } finally {
21865                             tp.kill();
21866                         }
21867                     } catch (IOException e) {
21868                         pw.println("Failure while dumping IPC traces from " + process +
21869                                 ".  Exception: " + e);
21870                         pw.flush();
21871                     } catch (RemoteException e) {
21872                         pw.println("Got a RemoteException while dumping IPC traces from " +
21873                                 process + ".  Exception: " + e);
21874                         pw.flush();
21875                     }
21876                 }
21877                 fd = null;
21878                 return true;
21879             }
21880         } finally {
21881             if (fd != null) {
21882                 try {
21883                     fd.close();
21884                 } catch (IOException e) {
21885                 }
21886             }
21887         }
21888     }
21889
21890     private final class LocalService extends ActivityManagerInternal {
21891         @Override
21892         public String checkContentProviderAccess(String authority, int userId) {
21893             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21894         }
21895
21896         @Override
21897         public void onWakefulnessChanged(int wakefulness) {
21898             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21899         }
21900
21901         @Override
21902         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21903                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21904             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21905                     processName, abiOverride, uid, crashHandler);
21906         }
21907
21908         @Override
21909         public SleepToken acquireSleepToken(String tag) {
21910             Preconditions.checkNotNull(tag);
21911
21912             ComponentName requestedVrService = null;
21913             ComponentName callingVrActivity = null;
21914             int userId = -1;
21915             synchronized (ActivityManagerService.this) {
21916                 if (mFocusedActivity != null) {
21917                     requestedVrService = mFocusedActivity.requestedVrComponent;
21918                     callingVrActivity = mFocusedActivity.info.getComponentName();
21919                     userId = mFocusedActivity.userId;
21920                 }
21921             }
21922
21923             if (requestedVrService != null) {
21924                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21925             }
21926
21927             synchronized (ActivityManagerService.this) {
21928                 SleepTokenImpl token = new SleepTokenImpl(tag);
21929                 mSleepTokens.add(token);
21930                 updateSleepIfNeededLocked();
21931                 return token;
21932             }
21933         }
21934
21935         @Override
21936         public ComponentName getHomeActivityForUser(int userId) {
21937             synchronized (ActivityManagerService.this) {
21938                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21939                 return homeActivity == null ? null : homeActivity.realActivity;
21940             }
21941         }
21942
21943         @Override
21944         public void onUserRemoved(int userId) {
21945             synchronized (ActivityManagerService.this) {
21946                 ActivityManagerService.this.onUserStoppedLocked(userId);
21947             }
21948         }
21949
21950         @Override
21951         public void onLocalVoiceInteractionStarted(IBinder activity,
21952                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21953             synchronized (ActivityManagerService.this) {
21954                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21955                         voiceSession, voiceInteractor);
21956             }
21957         }
21958
21959         @Override
21960         public void notifyStartingWindowDrawn() {
21961             synchronized (ActivityManagerService.this) {
21962                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21963             }
21964         }
21965
21966         @Override
21967         public void notifyAppTransitionStarting(int reason) {
21968             synchronized (ActivityManagerService.this) {
21969                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21970             }
21971         }
21972
21973         @Override
21974         public void notifyAppTransitionFinished() {
21975             synchronized (ActivityManagerService.this) {
21976                 mStackSupervisor.notifyAppTransitionDone();
21977             }
21978         }
21979
21980         @Override
21981         public void notifyAppTransitionCancelled() {
21982             synchronized (ActivityManagerService.this) {
21983                 mStackSupervisor.notifyAppTransitionDone();
21984             }
21985         }
21986
21987         @Override
21988         public List<IBinder> getTopVisibleActivities() {
21989             synchronized (ActivityManagerService.this) {
21990                 return mStackSupervisor.getTopVisibleActivities();
21991             }
21992         }
21993
21994         @Override
21995         public void notifyDockedStackMinimizedChanged(boolean minimized) {
21996             synchronized (ActivityManagerService.this) {
21997                 mStackSupervisor.setDockedStackMinimized(minimized);
21998             }
21999         }
22000
22001         @Override
22002         public void killForegroundAppsForUser(int userHandle) {
22003             synchronized (ActivityManagerService.this) {
22004                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22005                 final int NP = mProcessNames.getMap().size();
22006                 for (int ip = 0; ip < NP; ip++) {
22007                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22008                     final int NA = apps.size();
22009                     for (int ia = 0; ia < NA; ia++) {
22010                         final ProcessRecord app = apps.valueAt(ia);
22011                         if (app.persistent) {
22012                             // We don't kill persistent processes.
22013                             continue;
22014                         }
22015                         if (app.removed) {
22016                             procs.add(app);
22017                         } else if (app.userId == userHandle && app.foregroundActivities) {
22018                             app.removed = true;
22019                             procs.add(app);
22020                         }
22021                     }
22022                 }
22023
22024                 final int N = procs.size();
22025                 for (int i = 0; i < N; i++) {
22026                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
22027                 }
22028             }
22029         }
22030
22031         @Override
22032         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22033             if (!(target instanceof PendingIntentRecord)) {
22034                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22035                 return;
22036             }
22037             ((PendingIntentRecord) target).setWhitelistDuration(duration);
22038         }
22039
22040         @Override
22041         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22042                 int userId) {
22043             Preconditions.checkNotNull(values, "Configuration must not be null");
22044             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22045             synchronized (ActivityManagerService.this) {
22046                 updateConfigurationLocked(values, null, false, true, userId,
22047                         false /* deferResume */);
22048             }
22049         }
22050
22051         @Override
22052         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22053                 Bundle bOptions) {
22054             Preconditions.checkNotNull(intents, "intents");
22055             final String[] resolvedTypes = new String[intents.length];
22056             for (int i = 0; i < intents.length; i++) {
22057                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22058             }
22059
22060             // UID of the package on user userId.
22061             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22062             // packageUid may not be initialized.
22063             int packageUid = 0;
22064             try {
22065                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22066                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22067             } catch (RemoteException e) {
22068                 // Shouldn't happen.
22069             }
22070
22071             synchronized (ActivityManagerService.this) {
22072                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22073                         /*resultTo*/ null, bOptions, userId);
22074             }
22075         }
22076
22077         @Override
22078         public int getUidProcessState(int uid) {
22079             return getUidState(uid);
22080         }
22081     }
22082
22083     private final class SleepTokenImpl extends SleepToken {
22084         private final String mTag;
22085         private final long mAcquireTime;
22086
22087         public SleepTokenImpl(String tag) {
22088             mTag = tag;
22089             mAcquireTime = SystemClock.uptimeMillis();
22090         }
22091
22092         @Override
22093         public void release() {
22094             synchronized (ActivityManagerService.this) {
22095                 if (mSleepTokens.remove(this)) {
22096                     updateSleepIfNeededLocked();
22097                 }
22098             }
22099         }
22100
22101         @Override
22102         public String toString() {
22103             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22104         }
22105     }
22106
22107     /**
22108      * An implementation of IAppTask, that allows an app to manage its own tasks via
22109      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22110      * only the process that calls getAppTasks() can call the AppTask methods.
22111      */
22112     class AppTaskImpl extends IAppTask.Stub {
22113         private int mTaskId;
22114         private int mCallingUid;
22115
22116         public AppTaskImpl(int taskId, int callingUid) {
22117             mTaskId = taskId;
22118             mCallingUid = callingUid;
22119         }
22120
22121         private void checkCaller() {
22122             if (mCallingUid != Binder.getCallingUid()) {
22123                 throw new SecurityException("Caller " + mCallingUid
22124                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22125             }
22126         }
22127
22128         @Override
22129         public void finishAndRemoveTask() {
22130             checkCaller();
22131
22132             synchronized (ActivityManagerService.this) {
22133                 long origId = Binder.clearCallingIdentity();
22134                 try {
22135                     // We remove the task from recents to preserve backwards
22136                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22137                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22138                     }
22139                 } finally {
22140                     Binder.restoreCallingIdentity(origId);
22141                 }
22142             }
22143         }
22144
22145         @Override
22146         public ActivityManager.RecentTaskInfo getTaskInfo() {
22147             checkCaller();
22148
22149             synchronized (ActivityManagerService.this) {
22150                 long origId = Binder.clearCallingIdentity();
22151                 try {
22152                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22153                     if (tr == null) {
22154                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22155                     }
22156                     return createRecentTaskInfoFromTaskRecord(tr);
22157                 } finally {
22158                     Binder.restoreCallingIdentity(origId);
22159                 }
22160             }
22161         }
22162
22163         @Override
22164         public void moveToFront() {
22165             checkCaller();
22166             // Will bring task to front if it already has a root activity.
22167             final long origId = Binder.clearCallingIdentity();
22168             try {
22169                 synchronized (this) {
22170                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22171                 }
22172             } finally {
22173                 Binder.restoreCallingIdentity(origId);
22174             }
22175         }
22176
22177         @Override
22178         public int startActivity(IBinder whoThread, String callingPackage,
22179                 Intent intent, String resolvedType, Bundle bOptions) {
22180             checkCaller();
22181
22182             int callingUser = UserHandle.getCallingUserId();
22183             TaskRecord tr;
22184             IApplicationThread appThread;
22185             synchronized (ActivityManagerService.this) {
22186                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22187                 if (tr == null) {
22188                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22189                 }
22190                 appThread = ApplicationThreadNative.asInterface(whoThread);
22191                 if (appThread == null) {
22192                     throw new IllegalArgumentException("Bad app thread " + appThread);
22193                 }
22194             }
22195             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22196                     resolvedType, null, null, null, null, 0, 0, null, null,
22197                     null, bOptions, false, callingUser, null, tr);
22198         }
22199
22200         @Override
22201         public void setExcludeFromRecents(boolean exclude) {
22202             checkCaller();
22203
22204             synchronized (ActivityManagerService.this) {
22205                 long origId = Binder.clearCallingIdentity();
22206                 try {
22207                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22208                     if (tr == null) {
22209                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22210                     }
22211                     Intent intent = tr.getBaseIntent();
22212                     if (exclude) {
22213                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22214                     } else {
22215                         intent.setFlags(intent.getFlags()
22216                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22217                     }
22218                 } finally {
22219                     Binder.restoreCallingIdentity(origId);
22220                 }
22221             }
22222         }
22223     }
22224
22225     /**
22226      * Kill processes for the user with id userId and that depend on the package named packageName
22227      */
22228     @Override
22229     public void killPackageDependents(String packageName, int userId) {
22230         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22231         if (packageName == null) {
22232             throw new NullPointerException(
22233                     "Cannot kill the dependents of a package without its name.");
22234         }
22235
22236         long callingId = Binder.clearCallingIdentity();
22237         IPackageManager pm = AppGlobals.getPackageManager();
22238         int pkgUid = -1;
22239         try {
22240             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22241         } catch (RemoteException e) {
22242         }
22243         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22244             throw new IllegalArgumentException(
22245                     "Cannot kill dependents of non-existing package " + packageName);
22246         }
22247         try {
22248             synchronized(this) {
22249                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22250                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22251                         "dep: " + packageName);
22252             }
22253         } finally {
22254             Binder.restoreCallingIdentity(callingId);
22255         }
22256     }
22257 }